การลบไฟล์ออกจากรายการแบบโต้ตอบ


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 loop ดังนั้น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ก่อนหน้านี้จะถูกลบ?
Francesco Turco

5
ไม่เพียงyแต่ชื่อใด ๆ yเริ่มต้นด้วย เห็นได้ชัดว่าrmเพียงแค่ดูตัวละครแรกของสิ่งที่ได้รับการตอบสนอง: 'y' คือใช่ไม่มีอะไรอื่น
chepner

2

สำหรับบางสิ่งที่นักเล่นกว่าตอบใช่หรือไม่ใช่สำหรับแต่ละไฟล์คุณสามารถใช้iselectสำหรับการเลือกแบบ ncurses แบบอินเทอร์แอคทีฟ เช่น

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

หรืออนุญาตการเลือกไฟล์ใน dir ปัจจุบัน:

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

ซึ่งจะแสดงรายการแบบเต็มหน้าจอ (เทอร์มินัลแบบเต็ม) ซึ่งสามารถเลือกและยกเลิกการเลือกไฟล์ได้โดยการกด SPACE กด ENTER เพื่อยอมรับการเลือกของคุณ (รายการที่เลือกจะถูกพิมพ์ใน stdout) หรือqเพื่อออกจาก (ไม่มีสิ่งใดพิมพ์ไปยัง stdout) กดhเพื่อขอความช่วยเหลือ

สังเกตecho rm- ฉันได้เขียนแบบนั้นเพื่อการทดสอบ เปลี่ยนเป็นเพียงแค่rmคุณมั่นใจว่าคุณเข้าใจในสิ่งที่กำลังทำอยู่

นอกจากนี้โปรดทราบว่าxargsมีการใช้ที่นี่พร้อม\nเป็นตัวคั่นอินพุต สิ่งนี้จะไม่ทำงานหากชื่อไฟล์ใด ๆ มีตัวอักษรป้อนบรรทัดอยู่ สำหรับเรื่องนั้นการiselectทำงานไม่ถูกต้อง - คาดว่าหนึ่งรายการต่อบรรทัด - โชคiselectไม่ดีที่ไม่มีตัวเลือกสำหรับอินพุตหรือเอาต์พุตที่สิ้นสุดด้วยค่า null

iselectได้รับการบรรจุสำหรับเดเบียนอาจเป็น Ubuntu และ distros อื่น ๆ ด้วย หน้าแรกอยู่ที่http://www.ossp.org/pkg/tool/iselect/

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.