セミ初心者自動化のためにawkスクリプトを試してください。理論的には簡単なはずです。
すべて .lst で終わるファイルセットです。各ファイルには、特定の文字列を含む行(数百行)があります。 「ウォール」という言葉を例に挙げてみましょう。私がしたいのは、各行が(i)ファイル名と(ii)出力文字列で終わるファイルで終わることです。 「部分」は個別に機能しますが、(共通出力ファイルを生成するために)一緒に結合する方法をまだ把握していません。
したがって、3つの* .lstファイル(file1.lst、waste.lst、blah.lst)があるとしましょう。次の方法を使用してファイル名をファイルに出力できます(間違いなくより良い方法がありますが、うまくいきます...)。
ls -l *.lst | awk '{ print "File: " $9 }' > filenames.dat
さらに、次の方法を使用して、各* .lstファイルに「Wall」を含む行を共通ファイルに簡単に出力できます。
awk '/Wall/{print}' *.lst > wallvals.dat
さまざまな方法で2つの方法を後処理してマージできますが、awkを使用してすべての行を1行で実行する方法を見つけたいと思います。したがって、生成された出力ファイルは次のようになります。
File: file1.lst Wall data 4.54
File: trash.lst Wall data 3.44
File: blah.lst Wall data 333.66
私はさまざまなパイピング方法を試したか、awkパラメータ内にさまざまなビットを入れ子にしようとしましたが、何も機能しませんでした(エラーメッセージを生成することが目的ではない限り)。
事前に明確なガイドラインを理解してください...
ベストアンサー1
現在処理中のファイルのファイル名はawk
特殊変数で確認できますFILENAME
。つまり、awk
2 番目のコマンドを次のように調整できます。
awk '/Wall/ { printf "%s:%s\n", FILENAME, $0 }' *.lst
または気に入らない場合はprintf
、
awk '/Wall/ { print FILENAME ":" $0 }' *.lst
または、出力フィールド区切り記号を使用OFS
して
awk -v OFS=: '/Wall { print FILENAME, $0 }' *.lst
これにより、ファイル名とパターンに一致する行が出力され、その間にコロンが含まれます。
これはgrep
次のコマンドと同じ効果があります。
grep -H 'Wall' *.lst
...ここで、検索文字列が拡張正規表現ではなくデフォルトの正規表現として使用されるという点でいくつかの違いがあります(ただし、この場合は重要ではありません)。この-H
オプションは標準ではなく、grep
複数のファイル名が指定されている場合は必要ありません。grep 'Wall' /dev/null *.lst
同じコマンドを作成するより標準的な方法です(複数のパス名が指定されている場合、ユーティリティは常に一致する各ファイル名を出力します)。
欲しいなら精密質問に記載されている出力形式を確認したら、形式printf
文字列を修正してください。
awk '/Wall/ { printf "File: %s\t%s\n", FILENAME, $0 }' *.lst
または、
awk '/Wall/ { print "File: " FILENAME "\t" $0 }' *.lst
File:
これにより、ファイル名、タブ、行が続く文字列が出力されます。
最初のコマンドについては次のようになります。一般的に言えば解析された出力は悪い考えですls
。部分的にはほとんど常に不要で見苦しいからであり、部分的には出力が主に見るためのものだls
からです(ファイル名に追加の形式が適用される場合があります)。これは、ほぼ常に有効なファイル名をすべて読み取ることができないことを意味します。バラよりなぜ`ls`を解析しないのですか*(そしてどうすればいいですか?)