私は入れ子になったディレクトリ構造に散らばっている多数のXMLファイルを使って作業しています。
私は以下を試しました:
$ find . -name "*.xml" -type f | xargs -- xmllint --format
問題は、画面にフォーマットされたXML出力を生成しますが、ファイルを変更しないことです。
実際のファイルの内容を変更するようにこのコマンドをどのように変更できますか?
答え1
find
これは、次のことを直接使用して行うことができます-exec
。
find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;
渡されたコンテンツは、-exec
見つかった各ファイルに対して1回呼び出され、{}
テンプレートパラメータを現在のファイル名に置き換えます。\;
コマンドの最後で find を使用すると、対応する行が終了します。
xargs
xmllint
この場合、入力ファイルと出力ファイル名は同じ呼び出しで指定する必要があるため、各ファイルに対して一度呼び出す必要があるため、実際に使用する必要はありません。
xargs
findから渡されたコマンドは一度に複数のファイルを処理し、リストが長い場合に必要です。この場合、単一のファイル名--output
をに渡す必要があるため、そうすることはできませんxmllint
。そうしないと、xargs
大量のファイルを処理すると、「引数リストが長すぎます」というエラーが発生する可能性があります。次のオプションを使用するファイル置換文字列xargs
もサポートされています。-I
find . -name "*.xml" -type f | xargs -I'{}' xmllint --output '{}' --format '{}'
find -exec
上記のコマンドと同じことを行います。フォルダの中に似たスペースに奇数文字が含まれている場合とオプションを使用する必要があります-0
。ただし、withを使用すると、このオプションは一度に1つのファイルしか処理できないため、withを直接使用できることを意味します。find
xargs
xargs
-I
-L 1
find
-exec
答え2
私は通常、いくつかの層の間接的な方法でこれらの問題を解決します。必要な操作を実行するシェルスクリプトを作成してから呼び出します。はじめにお勧めします
#! /bin/sh
for file
do
xmllint --format $file > $file.tmp && mv $file.tmp $file
done
1つまたは2つのファイルに対して手動で試してから、xargsで置き換えることができます。
find . -name "*.xml" -type f | xargs -- xmltidy.sh