นับจำนวนไฟล์ทั้งหมดในไดเรกทอรีเฉพาะด้วยนามสกุลเฉพาะ


32

ฉันต้องการนับจำนวนไฟล์ทั้งหมดในไดเรกทอรีเฉพาะที่ลงท้ายด้วยส่วนขยาย ".mp4"

ฉันได้รับคำสั่งดังต่อไปนี้:

ls -F |grep -v / | wc -l

มันนับไฟล์ทั้งหมดในไดเรกทอรีเฉพาะ แต่ฉันต้องการจำนวนไฟล์ที่ลงท้ายด้วย. mp4 นามสกุล

มีคำสั่ง Ubuntu สำหรับสิ่งนั้นหรือไม่?


2
คำตอบที่ง่ายถูกต้องตรงไปตรงมาคือ @ louis-matthijssen one ls -1การจัดการกับอักขระขึ้นบรรทัดใหม่ในกรณีนี้ควรแยกlsเอาต์พุต รายการที่ทำเครื่องหมายผิดสำหรับการใช้แฟล็ก -R
Rmano

คำตอบ:


19

ที่นี่คุณสามารถทำเช่นนี้

ls -lR /path/to/dir/*.jpg | wc -l

สิ่งนี้ให้คุณนับ


5
ทำไม-R? ทำไมต้องทำแบบเต็มstatเมื่อคุณต้องการชื่อไฟล์ ทำไมไม่ls -1 *.jpg| wc -l? (ตกลงไม่ทำงานถ้าคุณมีชื่อไฟล์ที่มีการขึ้นบรรทัดใหม่ในกรณีนี้คุณสมควรได้รับ ;-) ... )
Rmano

2
... และคำถามก็คือ "การนับจำนวนไฟล์ในไดเรกทอรี" นอกจากนี้จะแสดงรายการเนื้อหาย่อยทั้งหมดซ้ำซึ่งชื่อลงท้ายด้วย. jpgไม่ใช่ไฟล์ในไดเรกทอรีย่อยที่ลงท้าย.jpgด้วย คุณเคยทดสอบไหม
Rmano

1
คำถามที่ว่า "ไฟล์ในไดเรกทอรีที่ระบุ" ซึ่งหมายความว่าไม่ต้องการการเรียกซ้ำไดเรกทอรีย่อย
David Richerby

1
สิ่งนี้จะล้มเหลวหากมีไฟล์มากเกินไปในไดเรกทอรี (เพราะ*.jpgถูกขยายโดยเชลล์ไม่ใช่โดยls) และหากมีไฟล์ที่ชื่อขึ้นต้นด้วยยัติภังค์
David Richerby

2
@DavidRicherby .นี้ข้ามชื่อที่ขึ้นต้นด้วย แต่มันใช้งานได้ดีกับยัติภังค์ในชื่อยกเว้นเมื่อ/path/to/dirเป็นสตริงว่างหรือเส้นทางสัมพัทธ์เริ่มต้นด้วยยัติภังค์ แต่ผมผิดก่อนที่จะมีการกล่าวว่าตัวละครแทนที่ด้วยls ?ที่เกิดขึ้นเมื่อ stdout เป็นขั้ว แต่นี่เอาท์พุทเป็นท่อเพื่อส่งทุกตัวอักษรจากชื่อไฟล์เพื่อls ซึ่งทำให้คำตอบนี้ไม่ถูกต้องหากไม่มีหรือตั้งค่าสถานะเพื่อเปลี่ยนพฤติกรรมดังกล่าวเนื่องจากชื่อไฟล์อาจมีการขึ้นบรรทัดใหม่ คำตอบของ l0b0นั้นปราศจากปัญหาเหล่านี้ wc-q-b
Eliah Kagan

42

น่าเสียดายที่ปัญหาที่ไม่เป็นพิษเป็นภัยนี้แก้ไขได้ยากในลักษณะที่รองรับชื่อไฟล์ทั้งหมดและพกพาได้ นี่คือความปลอดภัย (มันจัดการไฟล์ที่ซ่อนเส้นทางที่มีช่องว่างขีดกลางและแม้กระทั่งการขึ้นบรรทัดใหม่) และเข้ากันได้กับ POSIX :

find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c

ถ้าคุณไม่อยากให้มันเป็น recursive -maxdepth 1เพียงแค่เพิ่ม

คุณไม่ควรแยกวิเคราะห์lsผลลัพธ์

ทดสอบ:

$ cd -- "$(mktemp -d)"
$ touch -- -foo.mp4 .bar.mp4 .bat.mp4 'baz.mp4
> ban.mp4'
$ find . -mindepth 1 -type f -name "*.mp4" -exec printf x \; | wc -c
4

เปรียบเทียบกับคำตอบที่ยอมรับได้ :

$ ls -lR ./*.mp4 | wc -l
3

หรือคำแนะนำอื่น ๆ :

$ find . -name "*.mp4" | wc -l
5
$ ls -1 *.mp4 | wc -l
ls: invalid option -- '.'
Try 'ls --help' for more information.
0
$ find . -name "*.mp4" | wc -c # Answer fixed at a later time
51
$ find . -name "*.mp4" | wc -l
5
$ find . | grep -i ".mp4$" | wc -l
5
$ ls . | grep ".mp4$" | wc -l
3

2
ถึงแม้ว่าคำตอบที่ถูกต้องและมีประสิทธิภาพคุณสามารถใช้แทน-printf x -exec printf x \;นั่นคือfind /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c ไม่จำเป็นต้องไม่มี-execภายนอกprintfคำสั่งซึ่งถ้ามีไฟล์จำนวนมากจะช้ามากเพราะfindมีการส้อม (2)ปิดสำเนาของตัวเองแล้วexecve /usr/bin/printf(2) ด้วย-exec printf x \;ที่จะต้องทำครั้งเดียวสำหรับแต่ละไฟล์
Eliah Kagan

-printfไม่รองรับ POSIXfindซึ่งเป็นสาเหตุที่ฉันไม่ได้ใช้
l0b0

1
ไม่เป็น-mindepthและ-maxdepthที่คุณใช้
Eliah Kagan

จุดดีฉันไม่ได้หยิบขึ้นมา!
l0b0

BSD findมี-mindepthและ-maxdepthไม่มี แต่-printfฉันชื่นชมการรวมของทั้งสอง
โจเซฟ

11

ไฟล์นี้จะค้นหาเรียงลำดับและแสดงรายการไฟล์ทั้งหมดตามนามสกุล:

find . -type f | sed 's/.*\.//' | sort | uniq -c

ยอดเยี่ยม ฉันเพิ่งจะเพิ่ม| sort -rnในตอนท้ายและอาจจะเป็น-mindepth 1เพียงผบ
Pablo

และอาจไปป์เพื่อhead -nให้ได้อันดับสูงสุด
Raman

คำตอบที่ยอดเยี่ยมเช่นนี้ขอบคุณมาก
Dennis Golomazov

5

ฉันคิดว่ามันง่ายมากตามคำสั่งดังต่อไปนี้

$ find . -name "*.mp4" | wc -l
8

หรือ

$ find . | grep -i ".mp4$" | wc -l
8

ฉันคิดว่าคำสั่งข้างต้นคำนวณจำนวนไฟล์และชื่อไดเรกทอรี *.mp4

ดังนั้นฉันขอแนะนำให้คุณใช้-type fตัวเลือกเป็นfindพารามิเตอร์ดังต่อไปนี้

$ find . -name "*.mp4" -type f | wc -l
8

นอกจากนี้ls -lRยังสามารถใช้เป็นfind .


2

ls -1 *.mp4 | wc -lคุณสามารถใช้

สิ่งนี้จะแสดงรายการไฟล์ทั้งหมดที่ลงท้ายด้วย.mp4การพิมพ์แต่ละไฟล์ในบรรทัดใหม่ ( ls -1 *.mp4) ไพพ์เอาต์พุตwcที่จะนับจำนวนบรรทัดใหม่โดยใช้-lแฟล็ก


ไม่แน่ใจว่าทำไมสิ่งนี้จึงถูกลดระดับลงจึงใช้งานได้
Panther

เนื่องจาก*.mp4ถูกขยายโดยเชลล์ไม่ใช่lsสิ่งนี้จะล้มเหลวหากมี.mp4ไฟล์จำนวนมากในไดเรกทอรีที่ไม่สามารถส่งผ่านรายการไปlsเป็นอาร์กิวเมนต์ได้
David Richerby

@Rmana ทดสอบในไดเรกทอรีที่มีไฟล์ชื่อ--.mp4
David Richerby

@DavidRicher โดยใช่คุณพูดถูก --จะแก้กรณีที่สอง; อดีตจะเพิ่มข้อความแสดงข้อผิดพลาด (คุณต้องการไฟล์จำนวนมาก!) และอีกคำถามที่ดีที่นี่ คดีมุม แต่ก็คุ้มค่าที่จะสังเกตเห็นใช่
Rmano

1
@Rmano หากไม่เพิ่ม-qหรือ-bสิ่งนี้ไม่สามารถขึ้นบรรทัดใหม่ในชื่อไฟล์ได้ หากคุณเรียกใช้ls -1 *.mp4จากเทอร์มินัลโดยไม่มีไพพ์lsเห็นstdout ของเทอร์มินัลและใช้-qโดยนัยพิมพ์?s แต่พฤติกรรมนั้นจะหายไปเมื่อส่งออกไปป์ไลน์ ls -1 *.mp4 | wc -lเกินจำนวนหากมีการขึ้นบรรทัดใหม่ ls -1 *.mp4 | catแสดงสิ่งที่wc"เห็น" (ในทำนองเดียวกัน-1ก็ส่อให้เห็นเมื่อ stdout ไม่ใช่เทอร์มินัลดังนั้นจึงเป็นตัวเลือก) ls -1q -- *.mp4 | wc -lเกือบจะใช้งานได้ แต่ไม่ใช่ไฟล์. mp4
Eliah Kagan

0

นี่ควรให้รายการไฟล์ที่มี. mp4

ls /path/to/directory | grep ".mp4$"

เมื่อรวมกับwc -lจะทำให้คุณนับ

ls /path/to/directory | grep ".mp4$" | wc -l

ถ้าคุณต้องการค้นหาเพื่อรวมไดเรกทอรีย่อย

ls -lR /path/to/directory | grep ".mp4$" | wc -l

ไม่นับ
Panther

มอบให้กับฉันเมื่อใช้กับwc -l
Back.Slash

ใช้ ls โดยไม่ต้องไพพ์เพื่อ grep และทำให้คำตอบสั้นลง โพสต์อย่างน้อยสองครั้งแล้ว
Panther

@ bodhi.zazen ls /directory/*.mp4ทำให้เชลล์ขยาย glob และดำเนินการบางอย่างเช่นls /directory/file1.mp4 /directory/file2.mp4 ...นี้จะล้มเหลวหากไดเรกทอรีมีไฟล์ mp4 มากกว่าที่สามารถส่งผ่านเป็นอาร์กิวเมนต์lsได้
David Richerby

@DavidRicherby - ไม่ใช่คำสั่ง ls ของฉันฉันใช้ find;)
Panther


0
ls | grep --count \.csv$

แทนที่ (.csv ด้วยนามสกุลที่คุณต้องการ)

คำอธิบาย: ฉันคิดว่ารูปแบบง่าย ๆ คือดึงรายการของไฟล์และนับนามสกุลด้วย grep \.เพื่อจับคู่.และ$จับคู่ส่วนขยายที่ท้ายบรรทัด มันทำงานได้เพราะเมื่อมีการไพพ์เอาต์พุตของ ls ชื่อไฟล์หนึ่งชื่อจะถูกส่งต่อบรรทัดซึ่งคุณสามารถตรวจสอบได้ด้วยการรัน:

ls | cat

1
หมายเหตุว่าแทนที่จะคุณยังสามารถใช้grep --count grep -c
Mohsin Raza

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