使っていますパラメータそしてRMそして探すfind で定義された特定のパターンに従うファイルを削除するには、次の手順を実行します。
touch file
find . -name file | xargs rm
上記のコードはすべてうまくいきますが、rmの-iオプションを入力して次を実行すると:
touch file
find . -name file | xargs rm -i
印刷:
rm:一般的な空のファイル「./file7」を削除しますか?ユーザー@ホスト:$
yまたはnを入力できません。したがって、ファイルは削除されません。
ここで問題は何ですか?
また、xargs -pパラメータが機能することもわかっていますが、より一般的です。すなわち、ユーザに特定のコマンドを実行するように促すメッセージが表示され、これはユーザが操作するのに不便である。
編集:シェルスクリプトでこれを使用したときに私が望むコマンドを実行しましたが、望ましくない find 結果も印刷したことがわかりました。
また、ls file2
cmd変数にコマンドを渡すと、file2の仕様は特に印刷されません。と入力すると同じことが起こります
rm -i file2
。ディレクトリ内のすべてのファイルを削除するように求められます。
これは私のスクリプトです。
#!/bin/bash
touch file{1..9} # Create 9 files named file1,file2...file9
echo -n 'command: ' # Prompt user
read -e cmd # read command
find . -exec ${cmd} '{}' +
私が考えることができる唯一の解決策は、ユーザーに好むモードを選択するように個別にメッセージを表示することです。次に、そのパターンを変数に保存し、パラメータとして渡します。探す堂々とした- 名前オプション。
このような:
#!/bin/bash
touch file{1..9} # Create 9 files named file1,file2...file9
echo -n 'command: ' # Prompt user for command
read -e cmd # read command
echo -n 'pattern: ' # Prompt user for pattern
read -e pattern
find . -name "$pattern" -exec ${cmd} '{}' +
しかし、このソリューションを使用しても探す出力は引き続き印刷され、パターンフィールドが空の場合(つまり、ユーザーがパターンを使用したくない場合)に問題が発生します。
どんなアイデアがありますか?
答え1
xargsはstdinからデータを読み込みます。 rm を使用するとrm -i
stdin( try ) から応答を読み取ろうとしますtouch test && echo y | r -i test ; ls test
が、stdin は xargs によって閉じられるため、(仮定) プロンプトで ctrl-d を押したかのように rm が応答します。
別の解決策はfindの-execオプションです。
touch test
find . -name test -exec rm -i {} \;
答え2
あなたはそれを使用することができますPOSIX -ok
find
コマンドを続行するかどうかを尋ねるオプションがあります(プロンプトを除いて同じ-exec
)。
touch file
find . -name 'file' -ok rm -f {} \;
出力
< rm ... ./file > ? _
答え3
ここでの問題は、(この場合)実行中のコマンドの(標準入力)がstdin
リダイレクトされ、ユーザー確認を取得するために使用されるファイル記述子であることです。xargs
rm
/dev/null
stdin
rm
この-a
オプションを使用すると、rmは以前にfindコマンドで生成された中間ファイルからファイルのリストを取得できます(この-a
オプションを使用するとxargs
影響を受けませんstdin
)。とにかく中間ファイルが必要なので、これが実際に望むものではないかもしれないことを知っています。以下を使用して、必要なものに似たより直接的な方法を得ることができます。
for i in $(find . -name file); do rm -i "$i"; done
答え4
同様の問題がありましたが、コマンドが出たときに驚きました。
find . -type f -name "*.txt" | xargs rm
このパターンに一致する読み取り専用ファイルが誤って削除されました。
後でマニュアルページで説明を見つけましたrm
。
ファイルが書き込み可能でなく、標準入力が端末であり、-fまたは--forceオプションが指定されていない場合、または-iまたは--interactive = alwaysオプションが指定されている場合、rmはユーザーにファイルを削除するかどうかを尋ねます。
プロンプトを表示する条件の1つは、標準入力が端末であり、他のコマンドの出力をrm
。
重要なレッスン:stdinが端末でない場合、rm
読み取り専用ファイルは警告なしに削除されます!
find
私の場合、書き込み可能なファイルのみを返すようにコマンドを変更することが解決策でした。
find . -type f -writable -name "*.txt" | xargs rm