私は取得したすべてのファイルを削除する簡単なプログラムを書いています。ファイルにスペースが含まれる可能性があるため、次のように引用符を追加しました。
find -name "*.scala" | xargs -d "\n" -I {} rm \"{}\"
次のエラーが原因で上記の操作が失敗します。削除できません。そのファイルやディレクトリはありません。しかし、同じファイルをリストすると、そのファイルはそこにあります。また、以下を実行し、bashを使用して実行すると機能します。
find -name "*.scala" | xargs -d "\n" -I {} echo rm \"{}\" | bash
誰かが最初のケースが機能しない理由を説明できますか?
答え1
xargs -d "\n" -I {} rm \"{}\"
これは、GNU coreutils バージョンが区切り文字を指定するオプションをサポートすると仮定xargs
します。-d
find
で見つかったパス名に二重引用符を追加するため、コマンドは機能しませんfind
。これは、への呼び出しがリテラルパス名を介して行われない./somedir/file.scala
ことを意味します。rm
"./somedir/file.scala"
例:
$ touch hello
$ touch '"hello"'
$ ls
"hello" hello
$ echo hello | xargs -d "\n" -I {} rm \"{}\"
$ ls
hello
引用符が削除されるため、bash
生成されたコマンドをパイプするときに機能します。bash
引用符を最初に追加するために余分な努力をしない場合でも機能することができます。
xargs -d "\n" -I {} rm {}
ファイルを正しく削除するには、次のようにします。
find . -type f -name '*.scala' -delete
またはまだ使用したい場合xargs
:
find . -type f -name '*.scala' -print0 | xargs -0 rm
find
xargs
との間のパス名を空の区切りリストとして渡します。空白(\0
)ただUnix システムでは、パス名に文字は使用できません。また、ファイル名には含めることはできませんが、/
改行文字は許可されます。
3番目のオプションは、rm
次から直接電話することですfind
。
find . -type f -name '*.scala' -exec rm {} +
スペース(または改行など)を含むパス名を命名ユーティリティに渡す方法が完全に明確であるため、引用は必要なく、{}
必要もありません。find