다음과 같은 명명 규칙을 따르는 파일이 많이 있습니다.
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 )
...번호순으로 정렬하세요. 아래 코드는 및 zsh
shell 에서 작동합니다 bash
.
그런 다음 다음과 같은 루프에서 스크립트를 호출할 수 있습니다.
k=10
while [ "${#files[@]}" -gt 0 ]; do
./myscript "${files[@]:0:k}"
files=( "${files[@]:k}" )
done
그러면 배열 의 첫 번째 전체가 ./myscript
호출된 다음 해당 항목이 배열에서 제거됩니다. 배열이 빌 때까지 계속됩니다.k
files
답변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_d
file9_d
file1_d
file2_d
이들 중 일부를 실행하려면 GNU zargs
및 GNU 모두에 대한 xargs
options 옵션이 있습니다 -P
myscript
.
답변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