xargs および rm+ ファイル名にスペースが含まれています。

xargs および rm+ ファイル名にスペースが含まれています。

私は取得したすべてのファイルを削除する簡単なプログラムを書いています。ファイルにスペースが含まれる可能性があるため、次のように引用符を追加しました。

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

findxargsとの間のパス名を空の区切りリストとして渡します。空白(\0ただUnix システムでは、パス名に文字は使用できません。また、ファイル名には含めることはできませんが、/改行文字は許可されます。

3番目のオプションは、rm次から直接電話することですfind

find . -type f -name '*.scala' -exec rm {} +

スペース(または改行など)を含むパス名を命名ユーティリティに渡す方法が完全に明確であるため、引用は必要なく、{}必要もありません。find

おすすめ記事