파일을 일괄적으로 스크립트에 피드

파일을 일괄적으로 스크립트에 피드

다음과 같은 명명 규칙을 따르는 파일이 많이 있습니다.

file1_d, file2_d, file3_d, ...,fileN_d

k첫 번째 파일을 입력으로 스크립트에 공급하고 다음 k파일을 두 번째 배치로 공급하고 싶습니다 . 예를 들어 배열을 사용하여 쉘 스크립트에서 이를 수행하는 쉬운 방법이 있습니까?

답변1

스크립트를 여러 번 실행하고 스크립트를 실행할 때마다 한 번에 하나씩 일괄적으로 스크립트에 대한 명령줄 인수로 파일을 제공하려고 한다고 가정합니다. (요구 사항에 대한 또 다른 해석은 스크립트가 표준 입력에서 파일을 읽고 k한 번에 하나씩 파일을 연결하여 제공하려는 것입니다. 아래 코드는 이러한 해석을 달성하기 위해 약간만 변경하면 됩니다.)

셸 에서는 bash스크립트에 제공된 청크 배열을 사용할 수 있습니다.

배열을 생성하려면 다음을 수행하십시오.

files=( file*_d )

그러면 와일드카드 패턴이 확장되고 file*_d결과 이름이 사전순으로 배열에 배치됩니다. 숫자 순서로 파일 이름이 필요하고 숫자가 0으로 채워지지 않은 경우 중괄호 확장을 사용하는 것이 더 쉽습니다.

files=( file{1..N}_d )

... 최대 수는 어디에 있습니까( 중괄호 확장 범위의 변수는 이해되지 않으므로 N변수가 아닌 실제 수 ).bash

zsh쉘 에서 다음을 사용하여 배열을 만들 수 있습니다.

files=( file<->_d )

...번호순으로 정렬하세요. 아래 코드는 및 zshshell 에서 작동합니다 bash.

그런 다음 다음과 같은 루프에서 스크립트를 호출할 수 있습니다.

k=10
while [ "${#files[@]}" -gt 0 ]; do
    ./myscript "${files[@]:0:k}"
    files=( "${files[@]:k}" )
done

그러면 배열 의 첫 번째 전체가 ./myscript호출된 다음 해당 항목이 배열에서 제거됩니다. 배열이 빌 때까지 계속됩니다.kfiles

답변2

에서는 zsh다음을 사용할 수 있습니다 zargs.

autoload zargs
zargs -l ${k?} -- file<->_d(n) -- myscript

bash 및 GNU 유틸리티를 사용하면 다음과 같은 작업을 수행할 수 있습니다.

xargs -r0n"${k?}" -a <(
  shopt -s failglob extglob
  pattern='file+([0123456789])_d' IFS=
  printf '%s\0' $pattern | sort -zV) myscript

glob n한정자를 사용하거나 파일 이름이 숫자로 정렬되어 예를 들어 중앙이 아닌 뒤쪽에 있는지 sort -V확인하세요 .file10_dfile9_dfile1_dfile2_d

이들 중 일부를 실행하려면 GNU zargs및 GNU 모두에 대한 xargsoptions 옵션이 있습니다 -Pmyscript.

답변3

GNU Parallel을 사용하여 일괄 처리를 병렬로 실행할 수 있습니다.

printf '%s\n' file*_d | parallel -j 2 -N "$k" ./myscript

스크립트가 stdin에서 읽히지 않지만 인수가 필요한 경우 :::다음을 사용하여 전달할 수 있습니다.

parallel -j 2 -N "$k" ./myscript ::: file*_d

-j동시에 실행할 작업 수를 지정하고(기본값은 사용 가능한 코어 수) -N해당 사례에 맞게 매개변수 제한이나 배치 크기를 지정합니다. 따라서 스크립트가 있는 경우 -j 2 -N 10시스템은 각각 10개의 파일 목록을 제공하며 언제든지 두 개의 다른 작업이 실행됩니다. 하나가 완료되면 모든 파일이 사용될 때까지 다른 하나가 시작됩니다.

병렬 작업을 실행하지 않으려면 다음을 통과할 수 있습니다.-j 1

답변4

단순 - 사용 xargs:

$ # Let's create 100 files with your naming convention
$ for i in {1..100} ; do touch $(printf "file%03d_d" $i) ; done

$ # Now let's process them in groups of 4 with this script:
$ cat /path/to/some/script.sh
#!/bin/bash
echo called with "$@"

$ ls | LC_ALL=C sort  | xargs -n 4 /path/to/some/script.sh
called with file001_d file002_d file003_d file004_d
called with file005_d file006_d file007_d file008_d
called with file009_d file010_d file011_d file012_d
...
called with file093_d file094_d file095_d file096_d
called with file097_d file098_d file099_d file100_d

C 로케일 접두사를 사용하는 것은 sort아마도 편집증적인 일입니다. 처리하려는 순서대로 파일을 정렬하려는 로케일/정렬 옵션을 사용하십시오.

궁금한 점이 있으면 데이터 세트를 완벽하게 나누지 않는 숫자에 대해 작동합니다.

$ ls | LC_ALL=C sort  | xargs -n 3 /path/to/some/script.sh
...
called with file091_d file092_d file093_d
called with file094_d file095_d file096_d
called with file097_d file098_d file099_d
called with file100_d

관련 정보