저는 bash와 코딩의 초보자이므로 양해해 주시기 바랍니다. 파일 목록(>1000)이 있고 이를 다른 형식으로 변환해야 합니다. 하지만 한 번에 40개의 파일에 대해 이 명령을 실행해야 합니다.
내가 시도한 것은 다음과 같습니다(그러나 이전에는 아무것도 없었기 때문에 기본적으로 명령을 실행하고 xargs가 작동하지 않습니다).
path=/home/dir1/dir2/dir3;
ls ${path} >> ${path}/LIST;
FILES=${path}/LIST;
xargs -n 40 <<$FILES | xargs commandname
답변1
문제는 목록을 읽는 데 있습니다.
FILES=${path}/LIST;
~해야 한다
FILES=$(<"${path}/LIST")
하지만,
xargs
파일을 직접 읽을 수도 있습니다xargs -a "${path}/LIST"
.xargs
전혀 반복할 필요가 없습니다.- 파일 이름 변수는 항상 큰따옴표로 묶어야 합니다!
- 경로에 공백이나 개행 문자가 포함되어 있으면 스크립트에 많은 문제가 발생하게 됩니다.
- 파일을 찾을 수 없는 경우 인수 없이 명령을 실행하지 못하도록 추가되었습니다
-r
.xargs
그래도,
대신 배열을 사용해야 합니다.
또한 파일 이름의 일부로 개행 문자와 관련된 문제를 방지하기 \0
위해 구분 기호로 및 를 함께 사용하는 데 익숙해 지는 것이 좋습니다 .xargs -0
shopt -s nullglob # avoid `*` as file if no files found in $path
path=/home/dir1/dir2/dir3
files=("${path}"/*)
printf '%s\0' "${files[@]}" | xargs -0 -r -n40 commandname
shopt -u nullglob
또는 parallel
대신 사용하십시오 xargs
:
shopt -s nullglob
parallel -j1 -n40 commandname ::: /home/dir1/dir2/dir3/*
답변2
zsh
를 바꾸 려면 ...을 사용하세요 bash
.
autoload zargs
zargs -rl40 -- /home/dir1/dir2/dir3/*(nN) -- commandname
( 정렬 순서 n
의 경우 일반적으로 번호 numericglobsort
가 매겨진 파일에 더 좋습니다.file10
뒤쪽에 file2
예를 들어) 및 N
for(따라서 nullglob
일치하는지 여부에 대해 불평하지 않고 숨겨진 파일이 없거나 읽을 수 없는 경우 보관됩니다.)/home/dir1/dir2/dir3/*
/home/dir1/dir2/dir3
답변3
나는 이와 같은 것이 GNU 확장을 사용하지 않고도 작동할 수 있다고 생각합니다.
set -- # clear positional arguments
for file in /home/dir1/dir2/dir3/*
do
[ -e "$file" ] || continue
set -- "$@" "$file"
if [ "$#" -eq 40 ]
then
commandname "$@"
set --
fi
done
# in case the number of files is a number not divisible by 40
if [ "$#" -gt 0 ] && [ "$#" -lt 40 ]
then
commandname "$@"
fi
명령이 무엇인지는 모르겠지만 다음과 같은 함수를 만들었을 때
commandname()
{
printf 'received %d arguments\n' "$#"
printf 'listing received filenames\n'
counter=0
for par in "$@"
do
counter="$(( counter+1 ))"
printf 'argument number %d: %s' "$counter" "$par" | LC_ALL=POSIX tr -d '[:cntrl:]'
printf '\n'
done
}
내가 알 수 있는 한, 수신된 메시지의 적절한 수를 표시하고 모두 올바르게 나열합니다. 여기에 나열된 대부분의 파일 이름을 테스트했습니다.쉘 스크립트의 파일 처리 견고성을 테스트하는 방법은 무엇입니까?(53개 파일).
또한 숨겨진 파일(점으로 시작하는 파일)은 찾을 수 없지만 OP에 작성한 내용도 찾을 수 없으므로 괜찮다고 생각합니다. 일반 파일만 필요한 -e "$file" ]
경우 [ -f "$file" ]
.
답변4
find /home/dir1/dir2/dir3 -maxdepth 1 -print0 |
xargs -0 -n 40 -P 0 commandname
파일 수가 40의 배수가 아닌 경우 commandname
프로세스 중 하나가 40개의 매개변수로 실행되지 않습니다.