質問: "ㅏ「ENDセクションで印刷された変数には、すべての行ではなく最後に見つかった行だけがあります。
ファイル1:
pattern .........
irrelevant text
irrelevant text
pattern .........
pattern .........
irrelevant text
奇妙なコード:
awk '{ for (i=1; i<=NR; i++)
if ($i ~ /^pattern/) a+=$0
}
END {print $a}' file1
END部分でパターンのある行だけを印刷したいと思います。
答え1
特定のパターンに一致するすべての行を収集し、最後に印刷したいようです。
あなたはこれを行うことができます
awk '/^pattern/ { a[++n] = $0 }
END { for (i = 1; i <= n; ++i) print a[i] }' file
これはa
配列として機能し、パターンに一致する各行を配列の新しい項目として追加します。最後に繰り返された項目を繰り返し、a
各項目を印刷します。
pattern
行全体の正規表現を一致させるのではなく、最初の列で正しいリテラル文字列を見つけるには、$1 == "pattern"
as条件を使用します。
しかし、これがみんなやりたいことをすれば使いやすくなります
awk '/^pattern/' file
pattern
または、最初の列のリテラル文字列と一致させたい場合
awk '$1 == "pattern"' file
これにより、パターンに一致する各行の基本操作が呼び出されます。pattern
2番目のバリアントを使用する場合は、それを最初の列として含めます。 「デフォルト動作」は行を印刷することです。
では、現在行の値を増加させるawk
算術演算となり、a += $0
数値として解釈されます。a
lineを文字列として変数に連結するには、または追加された文字列の前に改行文字を挿入する場合(デフォルト)をa
使用できます。しかし、私は何もここでやりたいことではないと思います。a = a $0
a = a ORS $0
ORS
答え2
コードにはいくつかの問題があります。
一致するパターンをテストするためにファイル内のすべての行にアクセスしようとしますが、
{ ... }
これをルールブロック()内で実行します。ただし、すべてのルールが処理されます。ファイルの各行について、これらのルールでは、現在処理されている行の内容にのみアクセスできます。パスワード{ for (i=1; i<=NR; i++) if ($i ~ /^pattern/) a+=$0 }
したがって、(条件が前に来ていないため、ファイル内のすべての行に対して)テストを試みます。フィールド1番から
NR
- どこNR
?ファイル内の現在の行の行番号、現在行のフィールド数の代わりにNF
追加してみてください。現在の行全体a
これが発生するたびに変数を指します。パターンが正規表現で提案された行の先頭にしか現れないことが事実である場合(アンカーのため)、結果はめちゃくちゃになることはできませんが、^
少なくとも非常に非効率的です。現在行を に追加しようとしている間、
a
次のように書き込みます。a+=$0
ただし、これは行(または少なくともスペースで区切られた最初のフィールド)が数値として正しく解釈できる場合にのみ明確に定義され、この場合は
a
/で始まるすべての行にのみ表示されます。ファイルに表示される個々の番号。行を数値として解釈できない場合、a
最終値は「0」です。END
ブロックで宣言print $a
しかし、これは印刷されますフィールド番号
a
変数の内容ではなく、現在の行の内容ですa
。ただし、変数はa
「0」(ポイント2で述べたように)なので、これは現在の行全体(別名$0
)を参照します。そして、ブロックのフィールド番号への参照はEND
常にファイルの最後の行を参照するので(ファイルの末尾に「現在」行がないため)、このステートメントは必然的にファイルの最後の行全体を印刷し、他にはありません。
特定のパターンに一致するライン印刷にのみ興味があるように思われるので、grep
このタイプのジョブ専用ツールを使用する方が簡単になります。
答え3
最初のフィールドを持つすべての行を印刷するには、pattern
内容をメモリに保存するのではなく、見つかったすべての行を印刷するだけです。
awk '$1=="pattern"' file
でも
grep -w '^pattern' file
逆に、各行を印刷するにはどのこの行のフィールドはですpattern
。以下を使用してください。
awk '{ for(i=1; i<=NF; i++){ if($i=="pattern"){ print; next}}}' file
またはフィールド値のみを探している場合スタートしかし、pattern
その後に他の文字があるかもしれません(コードで試している文字)。最初のフィールドだけが必要な場合は、次を使用してください。
awk '$1~/^pattern/' file
これはすべての分野に適用されます。
awk '{ for(i=1; i<=NF; i++){ if($i~/^pattern/){ print; next}}}' file
答え4
あなたの質問を正しく理解したら、一致するすべての行をリンクしたい^pattern
ので、これはあなたの要件を満たすでしょう。
echo $(grep '^pattern' infile)
awk
同じ
echo $(awk '/^pattern/' infile)
またはawk
単に使用してください:
awk '/^pattern/{ line = (line? line FS $0: $0) } END{ print line }' infile