ฉันสามารถค้นหาไฟล์ในโฟลเดอร์ที่มีสตริงข้อความเฉพาะโดยใช้คำสั่งนี้:
grep -lir 'string' ~/directory/*
ฉันจะย้ายไฟล์ที่ปรากฏในผลลัพธ์ข้างต้นไปยังตำแหน่งอื่นได้อย่างไร
ฉันสามารถค้นหาไฟล์ในโฟลเดอร์ที่มีสตริงข้อความเฉพาะโดยใช้คำสั่งนี้:
grep -lir 'string' ~/directory/*
ฉันจะย้ายไฟล์ที่ปรากฏในผลลัพธ์ข้างต้นไปยังตำแหน่งอื่นได้อย่างไร
คำตอบ:
grep -r
และเช่นเคยระวัง -r
ไม่ใช่ตัวเลือกมาตรฐานและในการใช้งานบางอย่างเช่นทั้งหมด แต่เป็นรุ่นล่าสุดของ GNU grep
มันตามลิงค์สัญลักษณ์เมื่อลงจากแผนผังไดเรกทอรีซึ่งโดยทั่วไปแล้วไม่ใช่สิ่งที่คุณต้องการ "บางที่ในแผนผังไดเรกทอรี
ในปรัชญา Unix คุณใช้คำสั่งเพื่อค้นหาไดเรกทอรีสำหรับไฟล์และอีกอันหนึ่งเพื่อดูเนื้อหา
ใช้เครื่องมือ GNU ฉันจะทำ:
xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
) mv -i --target-directory /dest/dir
แต่ถึงกระนั้นก็ตามจงระวังสภาวะการแย่งชิงและปัญหาด้านความปลอดภัยที่อาจเกิดขึ้นได้หากคุณเรียกใช้เป็นผู้ใช้รายหนึ่งในไดเรกทอรีที่ผู้ใช้อื่นสามารถเขียนได้
xargs
ออกจากก่อนที่จะอ่านไปยังจุดสิ้นสุดของไฟล์ arg ซึ่งไม่ควรเกิดขึ้นเว้นแต่ว่า xargs จะถูกฆ่าหรือล้มเหลวด้วยเหตุผลใดก็ตามซึ่งในกรณีนี้ฉันคาดว่าคุณจะเห็นข้อผิดพลาดเกี่ยวกับเรื่องนั้นด้วย
ใช้xargs
ร่วมกับmv
ไวยากรณ์ที่สามของ:mv [OPTION]... -t DIRECTORY SOURCE...
grep -lir 'string' ~/directory/* | xargs mv -t DEST
ระวังเกี่ยวกับไฟล์ที่มีตัวอักษรพิเศษ (ช่องว่างคำพูด) หากเป็นกรณีของคุณการกรองรายการด้วยsed
(การเพิ่มเครื่องหมายคำพูดรอบชื่อไฟล์ด้วยs/^/'/;s/$/'/
) อาจช่วยได้ แต่คุณต้องแน่ใจว่าเครื่องหมายคำพูดเหล่านี้จะไม่ปรากฏในชื่อไฟล์ GNU grep
มีตัวเลือก-Z
/ --null
เพื่อยกเลิกชื่อไฟล์ NUL
ทางเลือกอื่นสำหรับไวยากรณ์ที่สามที่mv
ใช้xargs
กับสตริงตัวยึดตำแหน่ง ( -I
)
ตัวเลือกอื่นคือการทดแทนคำสั่ง - $( )
หรือ backticks ``
(ในทุบตี) ดังกล่าวในคำตอบ ire_and_curses
หากชื่อไฟล์ของคุณไม่มีอักขระพิเศษใด ๆ (ช่องว่างหรือ\[*?
) ให้ใช้การแทนคำสั่ง :
mv `grep -lir 'string' ~/directory/*` destination/
ใช้เฉพาะฟีเจอร์ที่ระบุ POSIX และไม่มีข้อสันนิษฐานเกี่ยวกับชื่อไฟล์:
find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;
หมายเหตุ:
คุณพูดว่า "string" ไม่ใช่ "pattern" ดังนั้น -F
(การค้นหาสตริงคงที่) ที่grep
ดูเหมือนจะเหมาะสม
หากไดเรกทอรีปลายทางของคุณอยู่ที่ใดในไดเรกทอรีการค้นหาของคุณคุณอาจมีสภาพการแข่งขันที่ไม่พึงประสงค์
- สมมติว่าคุณมีไดเรกทอรีปลายทางเป็น 'ภายนอก' และต้องการย้ายไฟล์ XLS ทั้งหมดคุณสามารถลองคำสั่งด้านล่าง
sudo mv find /var/log/ -type f -name "*.xls"
/ ภายนอก /
grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name