Інтерактивне видалення файлів зі списку


13

Я хотів би видалити список файлів і попросити підтвердження. Список знаходиться у list.txtфайлі. Чому наступна команда не працює належним чином?

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

Попередня команда не чекає мене, але, на щастя, жоден файл не видалений.

Я використовую Bash.

Відповіді:


20

rm -iчитає свою відповідь зі стандартного вводу, який він успадковує з whileциклу. Отже, рядок тексту з list.txtвикористовується як відповідь на запитання "дійсно видалити?" питання. Для виправлення вам потрібно буде відокремити два джерела введення. Найпростіший спосіб - 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

Ви більше не переспрямовуєте стандартний вхід (fd 0) циклу while, тому rmчитатимете з терміналу за бажанням.

Можна також зробити:

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

Або з xargs GNU:

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

1
Тож якби я мав у списку файл з назвою y, попередній файл був би видалений?
Франческо Турко

5
Не просто y, а будь-яке ім'я, що починається з y. Мабуть, rmпросто дивиться на першого персонажа будь-якої відповіді, яку він отримує: "так" - так, нічого іншого немає.
чепнер

2

Для чогось більш фантастичного, ніж відповісти "так" або "ні" на кожен файл, ви можете використовувати 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не має можливості для введення чи виводу з нульовим завершенням.

iselectпакується для debian, ймовірно, для ubuntu та інших дистрибутивів. домашня сторінка за адресою http://www.ossp.org/pkg/tool/iselect/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.