ค้นหาไฟล์ทั้งหมดที่มีไฟล์อื่นที่ไม่มีนามสกุลต่างกันอยู่แล้ว


1

ฉันต้องการใช้คำสั่ง find เพื่อค้นหาไฟล์ทั้งหมดที่มีนามสกุล (avi) ที่ซึ่งชื่อไฟล์เดียวกันกับนามสกุลอื่น (mp4) ไม่มีอยู่จริง

ดังนั้นเมื่อพิจารณาไฟล์เหล่านี้:

a.avi
a.mp4
c.avi

มันควรจะส่งผลให้พบไฟล์ c.avi เท่านั้น


คุณใช้ระบบปฏิบัติการอะไร
and31415

@ and31415 เซิร์ฟเวอร์ Ubuntu
clamp

คำตอบ:


1

สิ่งนี้จะทำอย่างไร

find . -name '*.avi' -type f -execdir bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' {} \; -print

ฉันจะพยายามอธิบายวิธีการทำงาน

จริงๆแล้วมันง่ายมาก: ค้นหาไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันเพื่อให้ชื่อนั้นมีaviนามสกุล สำหรับแต่ละไฟล์สมมติว่าไฟล์นั้นX.aviทำงานในไดเรกทอรีที่มีอยู่ใน ( execdir) คำสั่ง:

bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' {}

ที่จะถูกแทนที่ด้วยชื่อไฟล์ในกรณีที่การทดสอบของเรา{} X.aviดังนั้นนี่คือ

bash -c 'f=("${0%avi}"*);((${#f[@]}==1))' X.avi

ณ จุดนี้ให้ฉันเน้นว่าสิ่งนี้ปลอดภัย 100% เกี่ยวกับช่องว่างและสัญลักษณ์ตลกอื่น ๆ ในชื่อไฟล์! ตอนนี้คุณเห็นข้อมูลโค้ดที่ bash จะทำงานหรือไม่ ฉันหมายถึงตัวอย่างนี้

f=("${0%avi}"*);((${#f[@]}==1))

มันจะถูกเรียกใช้งานโดยมีพารามิเตอร์ตำแหน่ง 0-th ตั้งเป็นชื่อไฟล์ของเรา X.aviในตัวอย่างการทดสอบของเรามันเป็น

ส่วน"${0%avi}"ขยายไปยังชื่อไฟล์โดยaviลบส่วนท้าย(btw ชื่อไฟล์นี้รับประกันว่าจะมีนามสกุลนี้ ณ จุดนี้) และส่วน"${0%avi}"*จะขยายไปยังไฟล์ทั้งหมดในไดเรกทอรีปัจจุบัน (จำไว้ส่วนที่มีไฟล์) ที่มี.aviส่วนขยาย. ในตัวอย่างทดสอบของเรานี่เป็นเช่น:

X.*

จากนั้นเราสร้างอาร์เรย์fจากสิ่งเหล่านี้และในที่สุดเราออกจากbashกระบวนการนี้ด้วยความสำเร็จหากfมีเพียงองค์ประกอบเดียว (ดังนั้นมีแนวโน้มมากมีfเพียงX.aviในตัวอย่างทดสอบของเรา) และความล้มเหลวเป็นอย่างอื่น หากนี่เป็นความสำเร็จเราจะพิมพ์ชื่อไฟล์


ขอโทษนะ แต่ถ้าคุณลงคะแนนฝากข้อความ มีโอกาสมากที่คุณจะไม่เข้าใจคำตอบของฉันอย่างลึกซึ้งและฉันยินดีที่จะให้ความกระจ่างแก่คุณ และคุณอาจเรียนรู้บางอย่างในกระบวนการ! :D
gniourf_gniourf

1
ฉันไม่ได้ลงคะแนน แต่ฉันอยากจะ ฉันสงสัยว่าสิ่งนี้จะได้ผล แต่ฉันไม่สามารถเข้าถึงระบบ * nix ได้ในขณะนี้ดังนั้นฉันจึงไม่สามารถทดสอบได้ ( คุณได้ทำการทดสอบแล้ว) โปรดอธิบายว่า / ทำไมคุณเชื่อว่าสิ่งนี้ใช้ได้ผลและเตรียมที่จะเรียนรู้บางสิ่งบางอย่างด้วยตัวเองเมื่อมีใครบางคนเข้ามาและบอกคุณว่าทำไมมันถึงไม่
สกอตต์

@Scott โปรดกลับมาอีกครั้งเมื่อคุณมีระบบ * ระวังและเราจะคุยกันเล็กน้อย ในระหว่างนี้อย่าลังเลที่จะลงคะแนน แต่ถ้าคุณทำเช่นนั้นโปรดใช้เวลา 2 นาทีเพื่อเคลียร์ข้อสงสัยของคุณว่ามันใช้งานไม่ได้ทำให้มั่นใจด้วยเหตุผลที่มั่นคง
gniourf_gniourf

บางทีคุณอาจไม่พอใจกับการขยายพารามิเตอร์ bash (เดี๋ยวก่อนเราอยู่ใน SU ไม่เหมือนในไซต์ที่มีคนมีความรู้) หากเป็นกรณีนี้ให้ลบความคิดเห็นของคุณ ให้ฉันบอกคุณฉันเชื่อว่าเป็นกรณีนี้เพราะใครก็ตามที่รู้ดีว่าทุบตีอย่างน้อยนิดจะเข้าใจตัวอย่างเล็ก ๆ น้อย ๆ นี้
gniourf_gniourf

1

วิธีการแก้ปัญหาด้วย 2 exec () s:

หา -name '* .avi' -print | \
  perl -n -e '$ x = $ _; $ x = ~ s / \. avi \ s * $ /. mp4 /; (-e $ x) || พิมพ์'

ขั้นตอน:

  1. นี่คือหุ่นที่คุณกำลังมองหา
  2. สำหรับทุกบรรทัดอินพุต / ไฟล์ให้ทดสอบไฟล์. mp4 ที่เกี่ยวข้องและ echo ชื่อไฟล์. avi หากไม่พบ
    1. คัดลอกบรรทัดอินพุตไปที่ $ x
    2. แทนที่. mp4 สำหรับ. avi ใน $ x (แต่จะอยู่ที่ท้ายบรรทัด)
    3. หากไฟล์. mp4 ที่เกี่ยวข้องนั้นมีอยู่เราจะใช้บรรทัดนี้มิฉะนั้นพิมพ์บรรทัดอินพุต

0

ตัวเลือกอื่น: ค้นหาทั้งหมด.mp4และ.aviไฟล์จากนั้นลบไฟล์ที่มีนามสกุลทั้งสองจากรายการและกำจัดไฟล์. mp4 ที่เหลืออยู่:

find . -name '*.avi' -or -name '*.mp4' |
rev | sort -t. -k2 -k1,1 | uniq -s3 -u | grep -v '^4pm' | rev | sort

(สมมติว่าไม่มีไฟล์ใดขึ้นบรรทัดใหม่ในชื่อ)


-1

วิธีแก้ปัญหาด้วย 3 exec () s:

find . -name '*.avi' -print | \
  sed 's/\(.*\)\.avi$/if [ ! -f "\1.mp4" ]; then echo "\1.avi"; fi/' | \
  sh

ขั้นตอน:

  1. นี่คือหุ่นที่คุณกำลังมองหา
  2. ถอดไฟล์นามสกุล. avi ออก เขียนสตรีมของคำสั่ง sh ที่ทดสอบไฟล์. mp4 ที่เกี่ยวข้องและ echos ชื่อไฟล์. avi หากไม่พบ
  3. ประเมินคำสั่ง sh

touch '" ]; then rm -rf /; [ ! -f ".avi'ฉันหวังว่าฉันจะทำได้ :Dแปลกใจ
gniourf_gniourf

อาร์กิวเมนต์สำหรับ / ต่อท่อนี้ Pro: ตายง่ายปรับได้ง่าย คอนดิชั่น: ท่อนี้สามารถทำสิ่งที่ไม่ดีภายใต้สถานการณ์ทางพยาธิวิทยา (เช่นในตัวอย่างของ gniourf_gniourf) ดังนั้นการรันด้วยสิทธิ์พิเศษที่ไม่มีการตรวจสอบเพิ่มเติมจะเป็นความคิดที่ไม่ดี
Scott Leadley
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.