liệt kê các tập tin được đánh số trong một phạm vi cụ thể


16

Tôi có một tập hợp các tập tin trong một thư mục được đánh số như sau:

file1.txt
file2.txt
...
file30.txt
...

Bây giờ, tôi muốn chạy một lệnh trên một phạm vi tệp cụ thể, giả sử từ 18 đến 31.

Cho đến nay tôi đã sử dụng các cách sau,

ba đối số

command file1[8-9].txt file2[0-9].txt file3[0-1].txt

Bây giờ giả sử tôi muốn mọi số khác,

vòng

for i in `jot - 18 31 2`; do echo file${i}.txt; done | xargs command

có vẻ như đó là một vòng lặp đáng tin cậy hơn (không gian làm việc)

for i in `jot - 18 31 2`; do echo "\"file${i}.txt\" "; done | xargs command

nhưng có vẻ như nên có một cách đơn giản hơn để làm điều này. Tôi đoán giải pháp tốt nhất là tạo một hàm bash sẽ trả về tập hợp các tệp cho dòng lệnh. Sau đó tôi có thể làm một cái gì đó như,

command `filerange file 18 31`

Có cách nào tốt hơn hoặc đề xuất để làm điều này một cách hiệu quả?

Tôi xin lỗi trước nếu tôi bỏ lỡ câu hỏi tương tự được trả lời ở một nơi khác trên web hoặc trên superuser.


Tôi đã cập nhật câu hỏi của mình để bao gồm một giải pháp sử dụng forvòng lặp cho phép khoảng trắng trong tên tệp bằng xargs. Nó dường như hoạt động nếu bạn không có bash 4. Nếu bạn có bash 4, thì chắc chắn sử dụng mở rộng cú đúp! Xem câu trả lời được chọn. Ổ cắm không biết xấu hổ để nâng cấp bash Snow Leopard
milkypostman

Câu trả lời:


25

Thử đi:

for file in file{18..31}.txt

Nó được gọi là "biểu thức trình tự" và nó là một phần của tính năng mở rộng cú đúp của Bash . Nó hoạt động trong Bash 3 và 4.

Tính năng tăng dần là mới đối với Bash 4. Bạn có thể có Bash 3.x.

Trong Bash 4, bạn có thể làm:

$ for i in {1..6..2}; do echo $i; done
1
3
5

Nhưng trong Bash 3, bạn phải làm điều này để có kết quả tương tự:

$ for ((i=1; i<=6; i+=2)); do echo $i; done

Hình thức tương tự tăng thêm một:

$ for ((i=1; i<=6; i++)); do echo $i; done

Bất kỳ số nào cũng có thể là biến hoặc biểu thức. Tuy nhiên, trong một biểu thức tuần tự, các số phải là hằng số

Dưới đây là một ví dụ sử dụng biểu mẫu đó trên các tệp của bạn:

for ((i=18; i<=31; i++))
do
    echo "file${i}.txt"
done

Một tính năng mới khác của biểu thức chuỗi trong Bash 4 là khả năng bao gồm các số 0 đứng đầu. Điều này hữu ích nếu bạn muốn tạo (và sử dụng) các tệp được đánh số có thể được sắp xếp đúng.

Trong Bash 4:

touch file{001..010}.txt

sẽ tạo các tệp có tên "file001.txt" thông qua "file010.txt". Tên của họ sẽ sắp xếp theo thứ tự dự kiến. Nếu không có các số 0 đứng đầu, "file10.txt" sẽ sắp xếp trước "file1.txt".

Để làm việc với các tệp, bạn có thể sử dụng cú pháp zero hàng đầu tương tự:

for file in file{001..010}.txt; do echo "$file"; done

Trong Bash 3, nếu bạn cần các số 0 đứng đầu, bạn cần tự đệm giá trị:

for i in {1..10}
do
    printf -v i '%03d' $i 
    echo "file${i}.txt"
done

Câu printflệnh sẽ trả trước giá trị của i với các số 0 đứng đầu, vì vậy chiều rộng là 3, ví dụ ("4" trở thành "004").

Biên tập:

Việc chứa các không gian trong tên tệp rất đơn giản:

$ touch "space name "{008..018..3}" more spaces"
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces
$ for f in "space name "{008..018..3}" more spaces"; do mv "$f" "${f}.txt"; done
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces.txt

Cảm ơn bạn! Tôi không biết nơi này đã là cả cuộc đời tôi. Một điều mà tôi không thể làm việc được là sự gia tăng dường như không hoạt động trong phiên bản bash OSX. tức là tôi không thể {1..10..2}làm việc trong bash OSX của mình.
milkypostman

Chà, đó là vì Snow Leopard (vì một số lý do) đang sử dụng bash 3.1. Đây là một vấn đề phần mềm.
milkypostman

@milkypostman: Tính năng tăng dần và các số 0 đứng đầu {01..10}là mới đối với Bash 4. Bạn có thể có Bash 3.x. Nếu bạn cần tính năng tăng hoặc sử dụng các biến cho ranh giới phạm vi, thì hãy sử dụng biểu mẫu này: for ((i=1; i<=10; i+=2}(hoặc i++để tăng thêm một). Bất kỳ số nào cũng có thể là biến hoặc biểu thức. Sau đó, để sử dụng giá trị bên trong forvòng lặp: echo "file${i}.txt". In Bash 3, if you need leading zeros, inside the for loop do: printf -vi '% 03d' $ i`, nó sẽ trả trước giá trị của các isố 0 đứng đầu, ví dụ chiều rộng là 3, ("4" trở thành "004").
Tạm dừng cho đến khi có thông báo mới.

Dennis, có cách nào bạn cập nhật giải pháp của mình để đưa vào biểu mẫu thay thế không. Là một bình luận, nó hơi khó hiểu với những gì tôi có thể nhận được.
milkypostman

@milkypostman: Xem câu trả lời đã được chỉnh sửa của tôi.
Tạm dừng cho đến khi có thông báo mới.
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.