Đếm tổng số tệp trong thư mục cụ thể với phần mở rộng cụ thể


32

Tôi muốn đếm tổng số tệp trong thư mục cụ thể kết thúc bằng phần mở rộng ".mp4".

Tôi đang nhận lệnh sau:

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

Nó đếm tất cả các tệp trong thư mục cụ thể, nhưng tôi muốn số lượng tệp kết thúc bằng phần mở rộng .mp4.

Có lệnh Ubuntu nào không?


2
Câu trả lời đơn giản, chính xác, đơn giản là @ louis-matthijssen. ls -1xử lý các ký tự dòng mới, trong trường hợp này, hợp lý để phân tích lsđầu ra. Cái được đánh dấu là sai khi sử dụng cờ -R.
Rmano

Câu trả lời:


19

Ở đây bạn có thể làm theo cách này

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

Điều này cho bạn tính


5
Tại sao -R? Tại sao làm đầy đủ statkhi bạn chỉ cần tên tệp? Tại sao không ls -1 *.jpg| wc -l? (ok, không hoạt động nếu bạn có tên tệp với dòng mới trong đó. Trong trường hợp đó bạn xứng đáng với nó ;-) ...)
Rmano

2
... Và câu hỏi là "đếm số lượng tệp trong một thư mục". Hơn nữa, điều này sẽ liệt kê đệ quy tất cả nội dung của các thư mục con có tên kết thúc bằng .jpg , không phải các tệp trong thư mục con kết thúc bằng .jpg. Bạn đã bao giờ thử nghiệm nó?
Rmano

1
Câu hỏi cho biết "các tệp trong một thư mục cụ thể", ngụ ý rằng đệ quy thư mục con không muốn.
David Richerby

1
Điều này cũng thất bại nếu có quá nhiều tệp trong thư mục (vì *.jpgđược mở rộng bằng shell chứ không phải bởi ls) và nếu có các tệp có tên bắt đầu bằng dấu gạch nối.
David Richerby

2
@DavidR Richby Điều này bỏ qua tên bắt đầu bằng .. Nhưng nó thực sự hoạt động tốt với các dấu gạch nối trong tên, ngoại trừ khi /path/to/dirchuỗi trống hoặc đường dẫn tương đối bắt đầu bằng dấu gạch nối. Nhưng tôi đã sai trước đây khi nói lsthay thế nhân vật bằng ?. Điều đó xảy ra khi thiết bị xuất chuẩn là thiết bị đầu cuối, nhưng ở đây đầu ra là một đường ống để lsgửi tất cả các ký tự từ tên tệp đến wc. Điều đó làm cho câu trả lời này sai mà không có -qhoặc -bcờ để thay đổi hành vi đó , vì tên tệp có thể chứa dòng mới. Câu trả lời của l0b0 không có vấn đề này.
Eliah Kagan

42

Thật không may, vấn đề lành tính này rất khó giải quyết theo cách hỗ trợ tất cả các tên tệp và có thể mang theo được. Điều này là an toàn (nó xử lý các tệp ẩn, đường dẫn chứa dấu cách, dấu gạch ngang và thậm chí là dòng mới) và tương thích POSIX :

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

Nếu bạn không muốn nó được đệ quy, chỉ cần thêm -maxdepth 1.

Bạn không nên phân tích lsđầu ra.

Kiểm tra:

$ 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

So sánh với câu trả lời được chấp nhận :

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

Hoặc các đề xuất khác:

$ 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
Mặc dù câu trả lời này là chính xác và mạnh mẽ, bạn có thể sử dụng -printf xthay vì -exec printf x \;. Đó là: find /path/to/directory -mindepth 1 -type f -name "*.mp4" -printf x | wc -c Không cần lệnh -execbên ngoài printf, nếu có nhiều tệp sẽ rất chậm , vì findphải tách (2) một bản sao của chính nó và sau đó thực thi (2) /usr/bin/printf . Với -exec printf x \;, điều đó phải được thực hiện một lần cho mỗi tệp .
Eliah Kagan

-printfkhông được hỗ trợ trong POSIXfind , đó là lý do tại sao tôi không sử dụng nó.
l0b0

1
Không phải -mindepth-maxdepth, mà bạn đã sử dụng.
Eliah Kagan

Điểm tốt, tôi đã không chọn về điều đó!
l0b0

BSD findchứa -mindepth-maxdepthkhông chứa -printfnên tôi đánh giá cao sự bao gồm của cả hai.
Joseph

11

Cái này tìm, sắp xếp và liệt kê tất cả các tệp theo phần mở rộng theo thứ tự:

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

Xuất sắc! Tôi chỉ cần thêm một | sort -rnở cuối và có thể là -mindepth 1nếu chỉ là thư mục hiện tại.
Pablo A

Và có thể đường ống head -nđể có được n hàng đầu.
Raman

thật là một câu trả lời tuyệt vời, cảm ơn rất nhiều
Dennis Golomazov

5

Tôi nghĩ rằng nó rất đơn giản như sau các lệnh.

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

hoặc là

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

Tôi nghĩ rằng các lệnh trên tính toán số lượng tệp và tên thư mục *.mp4

Vì vậy, tôi đề nghị bạn sử dụng -type ftùy chọn như findtham số như sau.

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

Ngoài ra, ls -lRcó thể được sử dụng nhưfind .


2

Bạn có thể sử dụng ls -1 *.mp4 | wc -l.

Điều này sẽ liệt kê tất cả các tệp kết thúc .mp4, in từng tệp trên một dòng mới ( ls -1 *.mp4), dẫn đầu ra wcsẽ đếm số lượng dòng mới bằng cách sử dụng -lcờ.


Không chắc chắn tại sao điều này bị hạ cấp, nó hoạt động
Panther

*.mp4được mở rộng bởi shell, nên ls, điều này sẽ thất bại nếu có quá nhiều .mp4tệp trong thư mục mà danh sách của chúng không thể được chuyển đến lsdưới dạng đối số.
David Richerby

@Rmana Kiểm tra nó trong một thư mục chứa một tệp có tên--.mp4
David Richerby

@DavidR Richby vâng, bạn nói đúng. --sẽ giải quyết trường hợp thứ hai; cái trước sẽ xuất hiện một thông báo lỗi (bạn cần rất nhiều tệp!) và một câu hỏi hay khác ở đây. Trường hợp góc, nhưng đáng chú ý, có.
Rmano

1
@Rmano Nếu không thêm -qhoặc -b, điều này không chấp nhận các dòng mới trong tên tệp. Nếu bạn chạy ls -1 *.mp4từ thiết bị đầu cuối của mình mà không có đường ống, lssẽ thấy thiết bị xuất chuẩn của nó là thiết bị đầu cuối và thực hiện -qnhư ngụ ý, in ?s. Nhưng hành vi đó biến mất khi đầu ra được dẫn. ls -1 *.mp4 | wc -lvượt qua nếu có dòng mới. ls -1 *.mp4 | catcho thấy những gì wc"nhìn thấy." (Tương tự, -1được ngụ ý khi thiết bị xuất chuẩn không phải là thiết bị đầu cuối, do đó, nó là tùy chọn.) ls -1q -- *.mp4 | wc -lGần như hoạt động, nhưng không phải với các tệp .mp4.
Eliah Kagan

0

Điều này sẽ cung cấp cho bạn danh sách các tập tin với .mp4

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

Khi kết hợp với wc -lsẽ cho bạn đếm

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

nếu bạn muốn tìm kiếm để bao gồm các thư mục con

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

không tính
Panther

đã đưa nó cho tôi khi được sử dụng vớiwc -l
Back.Slash

sử dụng ls mà không cần đường ống để grep và rút ngắn câu trả lời của bạn. Nó đã được đăng ít nhất hai lần bây giờ.
Panther

@ bodhi.zazen ls /directory/*.mp4làm cho trình bao mở rộng toàn cầu và thực thi một cái gì đó như thế ls /directory/file1.mp4 /directory/file2.mp4 ...này sẽ thất bại nếu thư mục chứa nhiều tệp mp4 hơn có thể được chuyển qua làm đối số ls.
David Richerby

@DavidR Richby - đó không phải là lệnh ls của tôi, tôi sử dụng find;)
Panther

0

Trong bash, một khu nghỉ mát lạnh để sử dụng mảng với global:

$ files=( *.mp4  )
$ echo ${#files[@]}
30

0
ls | grep --count \.csv$

Thay thế (.csv bằng tiện ích mở rộng bạn muốn)

Giải thích: Tôi nghĩ rằng một sơ đồ đơn giản là tìm nạp danh sách các tệp và đếm phần mở rộng bằng grep. \.để khớp .$khớp với phần mở rộng ở cuối dòng. Nó hoạt động vì khi đầu ra của ls được dẫn, một tên tệp được gửi trên mỗi dòng, bạn có thể xác minh bằng cách chạy:

ls | cat

1
Lưu ý rằng thay vì grep --count, bạn cũng có thể sử dụng grep -c.
Mohsin Raza

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.