web-dev-qa-db-ja.com

各行の最初の一致のみを印刷する方法は?

次のようなファイルがあります。

asd 123 aaa wrqiqirw 123
123 itiewth 123 asno 123
123 132 123 123 123
boagii 123 asdnojaneoienton 123

予想される出力は次のとおりです。

123
123
123
123

正規表現でパターンを検索する必要があります。そのようなことを実装する方法はありますか?

7
Andrew

pcregrepで、12*3のようなパターンで:

pcregrep -o1 '(12*3).*'

pcregrepまたはGNU grep -P

grep -Po '^.*?\K12*3'

pcregrepは文字より多いバイトで機能しますが、GNU grepは現在のロケールで定義されている文字で機能します(そして、入力に有効なテキストが含まれていることを確認する必要があります。現在のロケールでは))。

GNU grepは、パターンが空の文字列と一致する場合は何も出力しないことに注意してください。

8

すべての行で123の一致を表示するには、grepで十分です。
一致が最初、中間、または最後のいずれであるかは意味がありません。
123を要求すると、行が123の場合は123になります(質問が正しく表現されておらず、別のものが必要な場合を除きます)

$ grep -wo '123' file # -w: Word match  -o : return only matched string instead of the whole line (default grep operation)

あなたが正規表現で各行の最初の数(任意の数-任意の長さ)をキャッチする必要がある場合、これは仕事をします:

cat <<EOF >file1
asd 111 777 aaa wrqiqirw 123
333 123 itiewth 123 asno 123
4444 111 123 123 567
boagii what 666 asdnojaneoienton 123
EOF
grep -Po '^[0-9]+|^.*?\K[0-9]+' file1
#output
111
333
4444
666
4
George Vasiliou

POSIXLY:

LC_ALL=C sed -e 's/.*\(123\).*/\1/' <file

LC_ALL-Cは、ファイルに現在のロケールで無効な文字が含まれている場合にsedがクラッシュしたり予期しない結果を生成したりしないようにするために必要です。

また、1行に1つのエントリを生成しますが、firstではなくlastに一致しました。

GNU sedとPCREを使用して、最初のものを照合する場合:

LC_ALL=C sed -E 's/.*?(123).*/\1/'

-E拡張REはPOSIXの次のバージョンに含まれます)

3
cuonglm
sed -e '
   /\n/{P;d;}
   s/12*3/\n&\n/;D
' < inoutfile
3
user218374

Perlでは、単純に

Perl -lne 'print $& if /\d+/' inputfile

または標準入力から:

echo foo 123 bar 456 doo 789 | Perl -lne 'print $& if /\d+/'
123

正規表現\d+は、連続する数字の任意の文字列に一致し、$&は、一致する文字列を示します。

3
ilkkachu

すべての行にgrepを使用:

while IFS= read -r line; do printf '%s\n' "$line" | grep -o 123 | head -1; done < filename

あれは:

  • 各行を個別にチェックするためにループします。
  • grep -o一致する行全体ではなく、一致のみを取得します。
  • head -1最初の一致のみを取得し、次の一致は取得しません。
2
Zumo de Vidrio

awk

re='12*3' awk '{match($0, ENVIRON["re"])}; RSTART{print(substr($0, RSTART, RLENGTH))}' file
1
iruvar