次のコマンドを実行しようとしています。
ls -d a* | xargs -i sudo rm -rf {}/*
問題は、そのセクションを追加する/*
とコマンドが機能しないことです。ディレクトリの内容(ディレクトリ自体ではない)を削除したいと思います。
答え1
何についてrm -r a*/*
?これにより問題が解決します。
答え2
このようなコマンドはrm
ワイルドカードを拡張するためにシェルを使用するため、どこかでシェルを呼び出す必要があります。
おそらく
ls -d a* | xargs -i sh -c sudo rm -rf {}/*
答え3
(警告する:まだこのコマンドをテストしていません。オタナエラーがある可能性があります。echo
orとnoを最初に使用してすべてをls
試してくださいsudo
。 )
一般的なアドバイス:xargs
何かをする最も簡単な方法はほとんどありません。そうでない場合-i
(非推奨であり、-I {}
代わりに移植性を使用する)、xargs
標準または共通ツールで生成された入力形式は必要ありません。を使用すると-I
いくつxargs
かの用途がありますが、パイプを使用する方が簡単ですfind
。find -exec
拡張にはシェルが必要で{}/*
、そのシェルは{}
作業する実際のパスに置き換える必要があります。簡単な解決策は、シェルで1行ずつ実行することです。ドットファイルが省略されるため、3 つのパターンすべてがディレクトリ内のすべてのファイルをキャプチャするために使用されます。一部のパターンがどのファイルとも一致しない場合でも、既存のファイルを参照しない引数は無視される*
ため重要ではありません。rm -f
… |
while read -r line; do
sudo rm -rf -- "$line"/* "$line"/.[!.]* "$line"/..?*
done
シェルがワイルドカードを実行するには、ある時点でファイルを1つずつ処理する必要があるため、Xargsはここでは役に立ちません。ただし、一般的な手法が役に立つ可能性があるため、xargsからシェルにファイル名を返す方法があります。はシェルの引数_
です(部分的には後続の引数$0
に戻る必要はなく、で始まってもすべてが機能するようにするために存在します。そうしないとシェルのオプションとして扱われます)。これには2つのアプローチがあります。つまり、シェルに引数を繰り返すか、xargsに各シェル呼び出しに単一の引数を渡すように指示することです。$0
$1
-
… | xargs -I {} sudo sh -c 'for x; do rm -rf -- "$x"/* "$x"/.[!.]* "$x"/..?*; done' _ {}
… | xargs -I {} -n 1 sudo sh -c 'rm -rf -- "$1"/* "$1"/.[!.]* "$1"/..?*' _ {}
私はこれがls -d a*
おもちゃの例であり、1行に1つのファイル名を生成するより複雑なコマンドがあるとします。にls -d a*
なります。いいえls
ほとんどの実装では、印刷できない文字を透明に出力しないために機能します。…
検索命令の場合-exec
と同じようにしてください。
find a* -exec sh -c 'rm -rf -- "$1"/* "$1"/.[!.]* "$1"/..?*' _ {} \; -prune
答え4
別のオプションは、xargsを呼び出す代わりにシェルループを使用することです。
例えば
ls -d a* | while read dir; do sudo rm -rf "$dir"/*; done;
主に例を挙げるために、パイプの中央にシェル構成を配置することで、これら2つの技術を組み合わせることもできます。
ls -d a* | while read dir; do ls -d "$dir"/*; done | xargs -d \\n rm -rf
xargsのオプションは、-d
単に引数間の区切り文字が改行文字であることを指定することで、スペースを含むファイル名に関連する潜在的な致命的な問題を回避します(例deadly / file
:)