cutを使用せずに行の最初のパターンマッチを取得する

cutを使用せずに行の最初のパターンマッチを取得する

次のようなテキストがたくさんあります(テストとデータをできるだけ単純にするため)。

first 1 is the real 2 time the word matched 3 
appeared on the previous line but is 4 the fourth.
Every line can have more numbers 5 because numbers 6 are everywhere
I need to extract the number just after the word 7 that precedes 8

grep単語の後に続く最初の数字を抽出するためにテストされているコマンドは次のとおりです。

grep -Eoi ' [0-9]{1}'

出力は次のとおりです

 1
 2
 3
 4
 5
 6
 7
 8

希望の出力は次のとおりです。

 1
 4
 5
 7

cutまたは使用は許可されていませんawk

答え1

私はこれがgrepを習得する練習だと思います。純粋なgrepソリューションは次のとおりです。

一行で:

echo "first 1 is the real 2 time the word matched 3 " |grep -Eo '[0-9]' |grep -m1 -E '[0-9]'

残念なことに、最初はgrepを使用してもgrep -m1望ましい結果が得られませんでした。

複数行を含むファイルではループを使用する必要があります。

while read -r line; do
grep -Eo '[0-9]' <<<"$line" |grep -m1 -E '[0-9]'
done < file.txt

またはコマンドラインから:

while read -r line; do grep -Eo '[0-9]' <<<"$line" |grep -m1 -E '[0-9]';done < a.txt

出力は予想通りです。

答え2

それを使用することは許可されていますかsed

$ sed 's/[^[[:digit:]]*\([[:digit:]]\).*/\1/' << EOF
> first 1 is the real 2 time the word matched 3 
> appeared on the previous line but is 4 the fourth.
> Every line can have more numbers 5 because numbers 6 are everywhere
> I need to extract the number just after the word 7 that precedes 8
> EOF
1
4
5
7

答え3

使用できる二つ grepコマンドを使用すると、最初の10進数シーケンスの前のすべての項目が一致して返され、次に数値のみが一致して返されます。

grep -Eo '^[^0-9]*[0-9]{1,}' file | grep -Eo '[0-9]{1,}'

{1,}[注:AFAIK{1}は重複して10進数シーケンスを一致させようとしているため、これを使用しています。 ]

PCREモードの使用が許可されており、それをサポートしている場合は、可変幅のLookbehindアサーションを使用して、単一でgrep同じ操作を効果的に実行できます。grep\K

grep -Po '^[^0-9]*\K[0-9]+' file

\dまたは(10進数のPerlスタイル表現を使用して少し簡潔に):

grep -Po '^[^\d]*\K\d+' file

つまり、あなた以来いいえあなたの言葉です。いいえ自分で許可すると、perlスペースで区切られたフィールドに分割し、すべての数字で構成される最初のフィールドを見つけることができます。

perl -MList::Util=first -alne 'print first { /^\d+$/ } @F'

答え4

次のことを試すことができます。

grep -Eon ' [0-9]{1}' | sort -k1,1 -u

出力は次のとおりです(行番号が取引ブレーカーであるかどうかわからない)。

1: 1
2: 4
3: 5
4: 7

または、この式は目的の出力を提供します。

grep -Eon ' [0-9]{1}' | sort -k1,1 -u | grep -o ' .*'

出力(例の出力には先行スペースが含まれています):

 1
 4
 5
 7

関連情報