test_1_cfg.dat
내 폴더에는 , , test_2_cfg.dat
.... 등과 같은 200개의 파일이 있습니다 . 처음 40개 파일을 입력으로 포함하고 일부 프로세스를 실행하는 bash 스크립트와 다음 40개 파일을 읽고 다른 프로세스를 실행하는 또 다른 스크립트가 필요합니다.
그래서 파일 이름 목록을 가져온 다음 목록을 분할하는 방법을 생각하고 있지만 bash에서 이 작업을 수행하는 방법을 잘 모르겠습니다.
어떤 아이디어가 있나요?
답변1
방법 #1 - 머리와 꼬리 사용
이 명령을 사용하여 head
다음과 같이 파일 목록에서 처음 40개 파일을 추출할 수 있습니다.
$ head -40 input_files | xargs ...
다음 40개를 얻으려면:
$ tail -n +41 input_file | head -40 | xargs ...
...
$ tail -n +161 input_file | head -40 | xargs ...
동일한 기술을 사용하여 한 번에 40개씩 목록을 계속해서 따라갈 수 있습니다.
방법 2 - xargs 사용
하나의 변수에 모든 파일 이름이 있는 경우 xargs
이를 사용하여 목록을 X 요소 덩어리로 나눌 수 있습니다.
예
내 파일 이름이 1-200이라고 가정해 보겠습니다. 그래서 다음과 같은 변수에 로드합니다.
$ files=$(seq 200)
이 변수의 처음 몇 가지 항목을 볼 수 있습니다.
$ echo $files | head -c 20
1 2 3 4 5 6 7 8 9 10
이제 xargs
이를 사용하여 다음과 같이 나눕니다.
$ 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 ...
그런 다음 위 명령을 다른 명령에 전달하면 xargs
프로그램이 실행됩니다.
$ xargs -n 40 <<<$files | xargs ...
파일 목록의 내용을 변수에서 쉽게 액세스할 수 없는 경우 xargs
파일을 통해 목록을 제공할 수 있습니다.
$ 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 ...
방법 #3 - Bash 배열
파일 이름이 Bash 배열에 있다고 가정합니다. 이번에도 1부터 200까지의 일련의 숫자를 사용하여 파일 이름을 나타냅니다.
$ foo=( $(seq 200) )
다음과 같이 배열의 내용을 볼 수 있습니다.
$ echo ${foo[@]}
1 2 3 4 5 ....
이제 처음 40개를 얻으세요.
$ echo "${foo[@]:0:40}"
두 번째 40 등등:
$ echo "${foo[@]:40:40}"
...
$ echo "${foo[@]:160:40}"
답변2
완벽한 요리법은 다음과 같습니다 xargs
.
cat list_of_files | xargs -n 40 command
인용 출처 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.
각 그룹에 대해 서로 다른 작업을 수행하려면 다음 항목에 전달하기 전에 관련 행을 가져와야 합니다 xargs
.
sed -n '1,40p' list_of_files | xargs command1
sed -n '41,80p' list_of_files | xargs command2
...
답변3
참고로 저는 을 좋아 xargs -n 40 <<<$files
하지만 한 줄에 "40개의 매개변수"가 있으므로 그렇게 했습니다.
threads=10
xargs -n $((40/threads)) <<<$files
아니면 배열이면..
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