リストからファイルをインタラクティブに削除する


12

ファイルのリストを削除して、確認を求められます。リストはlist.txtファイルにあります。次のコマンドが正しく機能しないのはなぜですか?

while read i; do rm -i $i; done < list.txt

前のコマンドは私を待ちませんが、幸いなことにファイルは削除されません。

私はBashを使用しています。

回答:


19

rm -iwhileループから継承する標準入力から回答を読み取ります。したがってlist.txt、「本当に削除しますか?」に対する回答として、からのテキスト行が使用されています。質問。修正するには、2つの入力ソースを分離する必要があります。最も簡単な方法はread、別のファイル記述子から入力を取得することです。

while IFS= read <&3 -r i; do
  rm -i -- "$i"     # Quote the file name, not just to be safe,
                    # but because it's the right syntax.
done 3< list.txt

whileループの標準入力(fd 0)をリダイレクトしないため、rm必要に応じて端末から読み取ります。

または、次のこともできます。

IFS=$'\n' # set field separator to newline
set -f    # disable globbing upon command substitution
rm -i -- $(cat list.txt)

または、GNU xargsを使用:

xargs -rd '\n' --arg-file=list.txt rm -i --

1
リストに、という名前のファイルがあったy場合、前のファイルは削除されていたでしょうか?
フランチェスコターコ

5
だけでなくy、で始まる名前y。どうやら、rm受け取った応答の最初の文字を見るだけです。「y」はyes、それ以外はnoです。
-chepner

1

各ファイルに「はい」または「いいえ」と答えるよりも少し奇抜なものについてはiselect、インタラクティブなncursesベースの選択に使用できます。例えば

iselect -a -m < list.txt | xargs -d '\n' -r echo rm 

または、現在のディレクトリ内のファイルの選択を許可するには:

find . -maxdepth 1 -type f | iselect -a -m | xargs -d '\n' -r echo rm

これにより、全画面(全端末)ncursesベースのリストが表示され、SPACEキーを押すと、ファイルを自由に選択および選択解除できます。ENTERを押して選択を受け入れる(選択したエントリはstdoutに印刷されます)かq、終了します(stdoutに何も印刷されません)。hヘルプを押してください。

注意してくださいecho rm-私はテスト用にそのように書いています。それがrm何をしているのか理解できると確信できたら、それを変更してください。

また、xargsここで\nは入力セパレータとして使用されていることに注意してください。ファイル名に改行文字が含まれている場合、これは機能しません。その点については、iselectどちらも適切に動作iselectしません-行ごとに1つの項目が必要です-残念ながら、nullで終わる入力または出力のオプションはありません。

iselectdebian、おそらくubuntuや他のディストリビューション向けにパッケージ化されています。ホームページはhttp://www.ossp.org/pkg/tool/iselect/にあります

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.