リストからファイルを対話的に削除する

リストからファイルを対話的に削除する

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

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

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

バッシュを使っています。

答え1

rm -iwhileループから継承された標準入力から回答を読みます。したがって、list.txt「本当に削除してもよろしいですか?」への答えとして、次の1行のテキストが使用されます。質問。この問題を解決するには、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 --

答え2

iselect各ファイルにYesまたはNoで答えるよりも珍しい場合は、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ベースのリストを表示します。 ENTERを押して選択を適用するか(選択した項目が標準出力に印刷されます)、終了しますq(何も標準出力に印刷されません)。助けが必要な場合はタップしてくださいh

注意してくださいecho rm- テスト目的でこう書いています。rmそれが何をしているのかをよく理解したら、それを次のように変更してください。

また、xargsここではwithが\n入力区切り文字として使用されることに注意してください。ファイル名に改行文字が含まれていると機能しません。この問題でもiselect正常に動作しません。 1行に1つの項目が必要で、残念ながらiselect入力または出力をnullで終了するオプションはありません。

iselectDebian、Ubuntu、その他のディストリビューション用にパッケージ化されています。ホームページの場所は次のとおりです。http://www.ossp.org/pkg/tool/iselect/

関連情報