ฉันจะไพพ์ ls เป็น grep ได้อย่างไรและลบไฟล์ที่กรองโดย grep?


33

ฉันต้องการลบแพคเกจบางอย่างในไฟล์บ้านของฉัน แต่ชื่อไฟล์ยาวเกินไป ( google-chrome-stable_current_i386.deb) ดังนั้นฉันจึงตัดสินใจใช้คำสั่งls|grep chrome|rmเพื่อไพพ์ไฟล์เพื่อ grep เพื่อกรองไฟล์ chrome แล้วลบออก มันใช้งานไม่ได้ดังนั้นฉันอยากจะดูว่าฉันสามารถทำสิ่งนี้ได้อย่างไร


22
rm -i *chrome*.deb
Lambert

28
โดยทั่วไปฉันไม่ชอบเมื่อมีคนโพสต์คำว่า "ไม่ทำอย่างนั้น" แต่นี่เป็นหนึ่งในตัวอย่างที่ดีที่สุดของปัญหา XY ที่ฉันเคยเห็น คำถามที่แท้จริงของคุณคือ "ฉันจะลบไฟล์ที่มีชื่อยาวได้อย่างรวดเร็วได้อย่างไรโดยไม่ต้องพิมพ์สิ่งที่ออกทั้งหมด" และมีวิธีการมากมายที่ไม่เกี่ยวข้องกับการเอาออกจากไฟล์ls
Michael Mrozek

5
ใช้เพียงแค่-find find . -name "*chrome*" -delete
Boris the Spider


3
สองเซ็นต์ของฉันในฐานะผู้ใช้ StackExchange: ในอนาคตให้ถามคำถามของคุณในแบบทั่วไปมากขึ้นในขณะที่ให้รายละเอียดเกี่ยวกับสิ่งที่คุณได้ลอง "ฉันจะลบไฟล์ใด ๆ ในโฟลเดอร์ที่มีสตริงที่แน่นอนในชื่อไฟล์ได้อย่างไร" อาจเป็นวิธีที่ดีกว่าในการใช้วลี จากนั้นคุณสามารถเพิ่มเพียงอย่างเดียวได้ว่าคุณลองใช้การส่งlsผ่านgrepไปยังrmแต่ไม่สามารถใช้งานได้ ด้วยวิธีนี้คุณจะได้รับคำตอบที่ดีหนึ่งหรือสองเกี่ยวกับวิธี "ถูกต้อง" หรือ "ง่ายที่สุด" ในการทำงานให้สำเร็จแทนที่จะบังคับให้ใครสักคนให้คำตอบที่ดีเกี่ยวกับโซลูชันที่ไม่มีประสิทธิภาพ
Adrian

คำตอบ:


56

เกือบทำให้ฉันสะดุ้ง

  1. คุณอาจต้องการหยุดชี้ปืนลูกซองที่เท้าของคุณ โดยทั่วไปชนิดของการแยกใด ๆlsเป็นไปได้มากขึ้นมีความซับซ้อนและผิดพลาดได้ง่ายกว่าวิธีการที่จัดตั้งขึ้นเช่นfind [...] -execหรือglobs
  2. เปลือกของคุณก็Tabเสร็จสมบูรณ์ เพียงพิมพ์และกดrm google Tabหากยังไม่เสร็จสมบูรณ์ให้กดTabอีกครั้งเพื่อดูรายการไฟล์ที่ตรงกัน พิมพ์อักขระเพิ่มเติมของชื่อไฟล์เพื่อ จำกัด ให้แคบลงจนกว่าจะเสร็จสมบูรณ์จากนั้นเรียกใช้คำสั่ง
  3. ท่อ ! = พารามิเตอร์ อินพุตมาตรฐานคือสตรีมข้อมูลไบนารีซึ่งสามารถป้อนให้กับคำสั่งแบบอะซิงโครนัส พารามิเตอร์คือสตริงที่คั่นด้วยช่องว่างซึ่งส่งผ่านหนึ่งครั้งไปยังคำสั่งเพียงครั้งเดียวเมื่อเรียกใช้ สิ่งเหล่านี้ใช้แทนกันได้ยากมาก

1
ขออภัยถ้ามันดูเหมือนคำถาม n00b ฉันรู้ว่ามันโอเคที่จะใช้โดยทั่วไปเนื่องจากแพ็คเกจที่ระบุเป็นแพ็คเกจเดียวที่มี "chrome" ระบุไว้ในนั้น ดังนั้นการใช้ grep จะกรองไฟล์เพียงไฟล์เดียว ฉันค่อนข้างใหม่สำหรับ linux และฉันได้ทำสคริปต์ทุบตีมาแล้วมากมาย แต่ฉันยังไม่ทราบทุกสิ่ง: P รุนแรงเพื่อน
SpecialBomb

5
ไม่ได้หมายความว่าจะรุนแรง แต่เปลือกหอยเป็นสภาพแวดล้อมที่รุนแรงและไม่ยอมให้อภัยซ่อนอยู่หลังพื้นผิวที่เป็นมิตรกับผู้ใช้ ทำสิ่งที่ได้อย่างปลอดภัยเป็นเรื่องยากพอไม่เคยคิดอย่างปลอดภัยหรือแม้กระทั่งการได้อย่างถูกต้อง
l0b0

2
@SpecialBomb นี่เป็นคำตอบเดียวที่ถูกต้อง การอธิบายวิธีการเล็งปืนลูกซองให้ถูกต้องเพื่อตัดเท้าของตัวเองอย่างที่ทำตามคำตอบอื่น ๆ ไม่ใช่วิธีที่จะไป ใช้ความระมัดระวังเป็นพิเศษในการดำเนินการสุ่มสี่สุ่มห้าrm- อาจเป็นวิธีเดียวที่ใช้ทอด distro ของคุณ
Boris the Spider

@BoristheSpider Heh ฉันได้ทอด Ubuntu ไปแล้วสองครั้งในการติดตั้งไดรเวอร์การ์ดกราฟิก AMD ฉันได้ถามคำถามเกี่ยวกับเรื่องนั้นแล้ว AMD น่ากลัวฉันเลยถามว่ามีการแก้ไขทั่วไปหรือวิธีการเล่นเกมที่ดีกว่ากับ Linux บนการ์ด AMD หรือไม่
SpecialBomb

34

คุณยังสามารถใช้คำสั่ง find กับไวด์การ์ด:

find . -maxdepth 1 -name '*chrome*' -delete

โปรดทราบว่าอาร์กิวเมนต์ "-maxdepth" ช่วยให้มั่นใจได้ว่าการค้นหาจะทำงานได้ในไดเรกทอรีปัจจุบันเท่านั้นและจะไม่ถูกเรียกเก็บเงินในไดเรกทอรีย่อย


1
ข้อเสนอแนะสำหรับการปรับปรุง (ก) การใช้-inameชื่อไฟล์กรณีตาย (ข) ท่อที่จะxargsใช้-print0ธงfindและธง-0 xargsการใช้xargsอนุญาตให้คุณทำสิ่งต่าง ๆ เช่นลบ "โต้ตอบ" (ยืนยันการลบfoo?)
Christopher Schultz

3
ไม่จำเป็นต้องไพพ์ไปยัง xargs หากคุณใช้ตัวเลือก -exec:find . -name '*chrome*' -exec rm -i {} +
Johnny

4
สิ่งนี้จะไม่ลบในไดเรกทอรีย่อยซ้ำ? คุณอาจต้องระบุว่าmaxdepthเป็น 1
Tyzoid

32

คุณมีความคิดที่ถูกต้องเพียงแค่พลาดรายละเอียดบางอย่าง ตั้งแต่คุณจัดการกับรายการที่จะมาถึง STDIN และคาดว่าพารามิเตอร์ที่คุณจำเป็นต้องใช้rmxargs

ดังนั้น:

ls | grep chrome | xargs rm

ควรให้สิ่งที่คุณต้องการ

โปรดทราบว่าหากคุณต้องการลบทุกอย่างที่ไม่ใช่chromeไฟล์คุณสามารถเพิ่มลง-vในgrepคำสั่งได้

โปรดทราบว่าตามคำตอบอื่น ๆ สำหรับคำถามนี้อาจเป็นวิธีที่ไม่ดีในการทำสิ่งที่คุณต้องการให้สำเร็จ


ด้วยสิ่ง-vนี้จะไม่ลบทุกอย่างยกเว้นไฟล์ที่ตรงกันchromeหรือไม่ ผมไม่คิดว่านั่นคือสิ่งที่ OP ต้องการ ...
akivajgordon

ดูอีกครั้งคุณถูกแล้ว OP ต้องการ "กรองไฟล์ chrome" แต่ต้องการลบออก
John

ดูเหมือนว่าจะไม่มีความซับซ้อนเมื่อเทียบกับ "rm -i chrome " อย่างง่าย
chander

5
คำตอบที่ยอมรับใช้งานได้ แต่ดูคำตอบด้านล่างซึ่งอธิบายว่าทำไมมันเป็นความคิดที่ไม่ดี (โพสต์ความคิดเห็นนี้ที่นี่เพียงเพื่อประโยชน์ของผู้ที่หยุดทันทีที่พวกเขาเห็นเครื่องหมาย "ยอมรับ".)
Jim Davis

1
นี่เป็นคำตอบที่ได้รับการยอมรับ "ทำงาน" เฉพาะในกรณีที่ไม่มีชื่อไฟล์ "แปลก"ในlsเอาต์พุต ชื่อไฟล์ที่มีช่องว่างจะทำให้สิ่งนี้เสียหาย สิ่งนี้ก็เป็นอันตรายเช่นกันหากมีคนสร้างชื่อไฟล์ด้วยซอสพิเศษในไดเรกทอรีที่คุณใช้งาน เนื่องจากมีคนมากกว่าหนึ่งคนที่ชี้ให้เห็นแล้วอย่าแยกเอาต์พุตของ ls !
สตีเฟ่น P

11

ไม่แยกวิเคราะห์ผลลัพธ์ของ ls
คำแนะนำของฉันคือการหลีกเลี่ยงการแยกผลลัพธ์ของ ls [ 1 ]ยิ่งถ้าร่วมกับdelคำสั่ง สิ่งนี้ด้วยเหตุผลหลายประการส่วนใหญ่เกี่ยวข้องกับอักขระที่ไม่คาดคิดและไม่ได้รับอนุญาตตามปกติในชื่อไฟล์

แม้ว่าคุณควรคาดหวังว่าชื่อไฟล์ที่อยู่ในแพ็คเกจ Linux จะ"ทำงานได้ดี"แต่ปัญหานี้อาจปรากฏขึ้นหากไฟล์อื่นมีอยู่ในไดเรกทอรีเดียวกัน แต่คุณไม่ทราบหรือแจ้งให้ทราบล่วงหน้า

เป็นการดีกว่าที่จะใช้findการขยายแท็บ (เริ่มเขียนชื่อและกดTab) การขยายชื่อไฟล์ [ 2 ]เป็น*MyKey*...


วิธีแก้ปัญหาที่รวดเร็ว
เนื่องจากคุณต้องการเลือกแพ็คเกจทั้งหมด (ที่ลงท้ายด้วย.deb) ด้วย"google"ข้างในคุณสามารถสร้างคำขอด้วย wildcard * *google*.debและทำง่ายๆ

rm -i *google*.deb 

ที่จะเลือกชื่อไฟล์แต่ละชื่อด้วย"google" ที่อยู่ตรงกลางซึ่งจะเสร็จสิ้นเพื่อ.debนำเสนอในไดเรกทอรีปัจจุบัน ตัวเลือก-i(โต้ตอบ) จะแจ้งให้ยืนยันซึ่งเป็นนิสัยที่ดีเมื่อคุณลบไฟล์ที่มีการขยายพารามิเตอร์


ทางออกใกล้เคียงกับปรัชญาของความพยายามของคุณ
หากจุดประสงค์ของคุณคือการสร้างชิ้นส่วนบรรทัดคำสั่งของคุณหลังจากชิ้นดังนั้นคุณได้ทำlsหลังจากls | grep googleและหลังจากที่คุณตรวจสอบผลลัพธ์ของคุณคุณสามารถดำเนินการใน subshell $(...)ด้วย

rm -i $(ls | grep google)

ได้เร็วขึ้นและอันตรายมากขึ้นวิธี [ 3 ]คือการใช้งาน!!

ls | grep google
rm -i $(!!)

ที่จะดำเนินการคำสั่งสุดท้ายเสร็จในประวัติของคุณ คุณสามารถป้องกันตัวเองจากความจริงที่ว่าคุณไม่มีการควบคุมภาพของสายที่คุณจะดำเนินการถ้าคุณได้เปิดใช้งานตัวเลือกล่วงหน้าเปลือกด้วยhistverifyshopt -s histverify


5
touch 0 1 2 3 4 5 6 7 8 9
find . -name \[0-9] -ok rm {} \;

< rm ... ./0 > ? y
< rm ... ./9 > ? y
< rm ... ./8 > ? y
< rm ... ./7 > ? y
< rm ... ./6 > ? y
< rm ... ./5 > ? y
< rm ... ./4 > ? y
< rm ... ./3 > ? y
< rm ... ./2 > ? y
< rm ... ./1 > ? y
^C

... ใช้-name '*c*.deb'หรือใช้รูปแบบอื่นที่เหมาะสมกับคุณแทน


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