Bash chia một danh sách các tập tin


8

Tôi có 200 tập tin trong một thư mục như: test_1_cfg.dat, test_2_cfg.dat, .... và vân vân. Tôi cần đưa vào tập lệnh bash 40 tệp đầu tiên làm đầu vào và chạy một số quy trình, một tập lệnh khác để đọc 40 tệp tiếp theo và chạy quy trình khác.

Vì vậy, tôi đã nghĩ đến một cách để có một danh sách tên của các tệp và sau đó chỉ cần tách danh sách đó nhưng tôi không chắc làm thế nào để làm điều đó trong bash.

Bất kỳ ý tưởng?

Câu trả lời:


14

Phương pháp số 1 - Sử dụng đầu & đuôi

Bạn có thể sử dụng lệnh headđể lấy ra 40 tệp đầu tiên từ danh sách tệp như vậy:

$ head -40 input_files | xargs ...

Để có được 40 tiếp theo:

$ tail -n +41 input_file  | head -40 | xargs ...

...

$ tail -n +161 input_file | head -40 | xargs ...

Bạn có thể tiếp tục đi xuống danh sách, 40 cùng một lúc bằng cách sử dụng kỹ thuật này.

Phương pháp # 2 - Sử dụng xargs

Nếu bạn tình cờ có tất cả tên tệp của mình trong một biến, bạn có thể sử dụng xargsnhư vậy để chia danh sách thành các phần của số phần tử X.

Thí dụ

Giả vờ các tập tin của tôi được gọi là 1-200. Vì vậy, tôi tải chúng lên thành một biến như vậy:

$ files=$(seq 200)

Bạn có thể thấy một vài mục đầu tiên trong biến này:

$ echo $files  | head -c 20
1 2 3 4 5 6 7 8 9 10

Bây giờ chúng tôi sử dụng xargsđể chia nó ra:

$ xargs -n 40 <<<$files
1 2 3 4 5 6 7 8 9 10 ...
41 42 43 44 45 46 47 ...
81 82 83 84 85 86 87 ...
121 122 123 124 125 ...
141 142 143 144 145 ...
161 162 163 164 165 ...
181 182 183 184 185 ...

Sau đó, bạn có thể truyền lệnh trên cho lệnh khác xargsđể chạy chương trình của bạn:

$ xargs -n 40 <<<$files | xargs ...

Nếu nội dung của danh sách các tệp không dễ truy cập từ một biến, bạn có thể đưa ra xargsdanh sách qua tệp thay thế:

$ xargs -n 40 <input_file
1 2 3 4 5 6 7 8 9 10 ...
41 42 43 44 45 46 47 ...
81 82 83 84 85 86 87 ...
121 122 123 124 125 ...
141 142 143 144 145 ...
161 162 163 164 165 ...
181 182 183 184 185 ...

Phương pháp # 3 - mảng Bash

Giả sử bạn có tên tệp của mình trong một mảng Bash. Một lần nữa tôi đang sử dụng một chuỗi số 1-200 để thể hiện tên tệp của mình.

$ foo=( $(seq 200) )

Bạn có thể thấy nội dung của mảng như vậy:

$ echo ${foo[@]}
1 2 3 4 5 ....

Bây giờ để có được 40 đầu tiên:

$ echo "${foo[@]:0:40}"

40 thứ 2, v.v .:

$ echo "${foo[@]:40:40}"
...
$ echo "${foo[@]:160:40}"

Tôi thực sự thích nhào lộn xargs nhưng mảng bash cũng hữu ích. Một cái gì đó để tìm hiểu ở đây!
Matthias Kauer

8

Đây là một công thức hoàn hảo cho xargs:

cat list_of_files | xargs -n 40 command

Trích dẫn từ man xargs:

 -n number   Set the maximum number of arguments taken from standard input
             for each invocation of the utility.  An invocation of utility
             will use less than number standard input arguments if the
             number of bytes accumulated (see the -s option) exceeds the
             specified size or there are fewer than number arguments
             remaining for the last invocation of utility.  The current
             default value for number is 5000.

Để thực hiện các hành động khác nhau cho mỗi bộ, bạn cần nhận các dòng có liên quan trước khi chuyển chúng cho xargs:

 sed -n '1,40p' list_of_files | xargs command1
 sed -n '41,80p' list_of_files | xargs command2
 ...     

tuyệt quá!!! Cảm ơn bạn. Bây giờ tôi có thể phân chia các tệp, nhưng làm cách nào tôi có thể chọn, ví dụ: bộ thứ hai gồm 40 tệp cho tập lệnh khác?
Alejandro

1
@Alejandro Tham khảo bản cập nhật.
devnull

2

FYI, tôi YÊU xargs -n 40 <<<$filesnhưng vì nó "40 args" trên mỗi dòng tôi đã làm

threads=10
xargs -n $((40/threads)) <<<$files

hoặc nếu trong một mảng ..

n=(1 2 3 4 5 6)
xargs -n $((${#n[@]}/threads))

while read -r input; do
  for item in $input; do
    <..stuff..>
  done &
done <<< $(for x in ${n[@]}; do echo $x; done | xargs -n $((${#n[@]}/threads)))
wait

2
Vui lòng cố gắng cải thiện khả năng đọc bằng cách định dạng các ví dụ mã như (s. Unix.stackexchange.com/editing-help - hoặc nhấp vào? Ở góc trên cùng / bên phải của trình chỉnh sửa)
sbkyky
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.