多数のXMLファイルを再フォーマットします。

多数のXMLファイルを再フォーマットします。

私は入れ子になったディレクトリ構造に散らばっている多数の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 を使用すると、対応する行が終了します。

xargsxmllintこの場合、入力ファイルと出力ファイル名は同じ呼び出しで指定する必要があるため、各ファイルに対して一度呼び出す必要があるため、実際に使用する必要はありません。

xargsfindから渡されたコマンドは一度に複数のファイルを処理し、リストが長い場合に必要です。この場合、単一のファイル名--outputをに渡す必要があるため、そうすることはできませんxmllint。そうしないと、xargs大量のファイルを処理すると、「引数リストが長すぎます」というエラーが発生する可能性があります。次のオプションを使用するファイル置換文字列xargsもサポートされています。-I

find . -name "*.xml" -type f | xargs -I'{}' xmllint --output '{}' --format '{}'

find -exec上記のコマンドと同じことを行います。フォルダの中に似たスペースに奇数文字が含まれている場合とオプションを使用する必要があります-0。ただし、withを使用すると、このオプションは一度に1つのファイルしか処理できないため、withを直接使用できることを意味します。findxargsxargs-I-L 1find-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

関連情報