Bash 분할 파일 목록

Bash 분할 파일 목록

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

관련 정보