まだ入ってみませんが、awk
来年学ぶ内容です。私は以前に質問をし、これに私に考えを与えさせ、awk
効果がありました。ただし、すべてのファイル形式を入力して出力する方法がわかりませんawk
。
- すべての
.xml
ファイルを検索 - 横になる
file.xml
awk
スクリプトの実行- 別名で保存
file.xml
awk
bashで調べて見つけました。これしかし、私はそれが現在awkコードがファイルに再印刷する問題を解決するとは思わない.xml
。現在のスクリプトを実行することが私がしなければならないすべてですgawk -f file.sh < file.xml
。
私の目標は、すべての.xml
ファイルを検索し、コードを実行し、.xml
同じ場所に新しいファイルを保存することです。
編集:数回の検索後にこれをxmlに戻すことができました。
gawk -f awk.sh < file.xml > file.xml
答え1
他のツールを使用しても問題ない場合は、find
このコマンド、特に-execオプションを調べるか、xargs
このコマンドと組み合わせる必要があります。 (これも見てくださいfind ... -print0 | xargs -0 ...
)
答え2
解決すべきいくつかの問題があります。
AWKスクリプトにはディレクトリを検索する方法が組み込まれていないため、少なくともファイルのリストを含むAWKスクリプトを提供する必要があります。これはシェルまたは経由で行うことができますfind
。このリストをAWKに渡す方法もいくつかあります。
また、スクリプトが最初にコンテンツを正常に処理し、出力を一時ファイルに保存する場合にのみ、元のファイルを上書きするように注意する必要があります。
また、これらのXMLファイルで何をしたいのかを慎重に検討する必要があります。 XML(およびSGMLなどのすべての類似した「言語」)の構文は、解析するのが非常に困難です。
まず、最後の質問から始めて、標準入力に提供されている入力ファイルを処理し、結果を標準出力に書き込むフィルタープログラムになる簡単なスクリプトを作成する場合、最も重要なステップは次のとおりです。推測したように、コマンドラインからファイルリダイレクトを使用して簡単にテストできますが、入力ファイルを上書きまたは切り捨てないように注意する必要があります。
awk -f script.awk < input_file > output_file
いくつかの単純なシェル構文は、スクリプトが成功したかのように、出力ファイルの名前を同じ名前に変更して入力ファイルを変換するのに役立ちます(したがって、2番目のトラブルシューティング)。
awk -f script.awk < input_file > output_file && mv output_file input_file
前のコマンドのみ&&
が実行され、成功状態で終了します(終了コードは0
。
最後に、大容量ファイル操作の最初の問題を解決できるようになりました。ファイルリストに対して上記のコマンドを繰り返す最も簡単な方法は、一度に1つのファイル名を読み取り、上記のコマンドを使用して処理する単純な小さなシェルループを使用することです。
while read fn; do
awk -f script.awk < "${fn}" > "${fn}.out" && mv "${fn}.out" "${fn}" || break
done
プロセスが失敗すると、|| break
ループが終了し、失敗したファイルの部分ファイルが残りますawk
。.out
また、変数拡張を注意深く引用してください。これにより、スペースを含むファイル名を正しく処理できます。
もちろん、while read
ループは、ユーザーがファイル名を入力してから別の名前を入力するなどの操作を中断するか、EOF文字を送信するのを待ちます。したがって、非常に簡単に次のファイル名のリストを提供できますfind
。
find . -name '*.xml' -print | while read fn; do
....
これらすべてを小さなスクリプトで終了するか、コマンドラインに入力できます。
小さなシェルスクリプトを作成した場合は、while
コマンドライン引数のリストを繰り返すループを使用して、各引数を処理するファイル名として処理することもできます。これにより、多くのUNIXプログラムがコマンドラインで提供されているファイルのリストを処理するのと同じように、シェルファイル名拡張子を使用して処理するファイルのリストを生成できます。その後、for
次のループを使用できます。
for fn
do
....
(最初の行の変数名の後にはセミコロンはありません!)
AWKスクリプトを変更して、標準入力からファイル名のリストを読み込んでsystem()
呼び出すこともできますmv
。