標準入力リダイレクトを使用してループから対話的にファイルを削除する

標準入力リダイレクトを使用してループから対話的にファイルを削除する

rm -i変数$to_remove(1行に1つのパス)に格納されているファイルを対話的に(たとえば)削除する必要があります。残念ながら、標準入力がリダイレクトに使用されるため、私のコードは機能しません<<< "$to_remove"

while read -r f ; do
    rm -ir "$f"
done <<< "$to_remove"

どうすれば解決できますか?

答え1

更新:これがfindデータソースの場合は、代わりに配列を使用します。

readarray -t to_remove < <(find ...)
number_of_files=${#toremove[@]}
rm -i "${to_remove[@]}"

4以前のバージョンを使用している場合は、bashこのループを使用して配列を埋めます。

while IFS= read -r fname; do
    to_remove+=("$fname")
done < <(find ...)

改行文字を含むファイルではこれらのいずれも機能しませんが、可能であればこの場合を無視する方が簡単だと思います。ただし、4では、bash次の呼び出しを完全に省略できます。find

shopt -s nullglob globstar
to_remove=( "$WORKING_PATH"/**/* )

私はあなたがto_removeファイルからそれを埋めていると仮定します。そうしないでください。ファイルから直接読んでください。

while IFS= read -r fname <&3; do
    rm -i "$fname"
done 3< file.txt

また、標準入力を使用できるように、別々のファイル記述子を使用してファイルから読み込みますrm

(本当に読むことができない場合は、to_remove一時ファイルを使用します。

printf "%s" "$to_remove" > tmp.txt
while IFS= read -r fname <&3; do
    rm -i "$fname"
done 3< tmp.txt
rm tmp.txt

)

答え2

私はそれについて考えた。

IFS=$'\n'
for f in `echo "$to_remove"` ; do
    rm -ir "$f"
done

簡潔なバージョン:

IFS=$'\n'
rm -ir "$to_remove"

どちらのバージョンも期待どおりに動作します。


奇妙なことに、以下のコードは機能しません。

IFS=$'\n'
for f in "$to_remove" ; do
    rm -ir "$f"
done

なぜ?

関連情報