.xz
디렉토리를 반복하고 확장자가 있는 모든 파일을 찾는 코드가 있습니다.
문제는 각 반복 파일에 액세스하는 방법을 알 수 없는 것 같지만 .xz
내가 ROOTPATH
뭘 잘못하고 있는 걸까요?
ROOTPATH='/home/user/path'
for file in "$ROOTPATH"; do
find $PWD -name '*.xz'
echo "file is $file"
done
그러면 다음과 같은 파일이 출력됩니다.
/home/user/path/file1.tar.xz
/home/user/path/file2.tar.xz
그런 다음 echo
부품이 인쇄됩니다.
file is /home/user/path
다음과 같은 각 반복 항목에 어떻게 액세스할 수 있습니까?
/home/user/path/file1.tar.xz
/home/user/path/file2.tar.xz
감사해요
답변1
*.xz
경로의 파일을 일치시키기 위해 glob을 사용하지 않으며 , 그렇게 할 때 find
명령도 필요하지 않습니다. 그냥 해
ROOTPATH="/home/user/path"
for file in "$ROOTPATH"/*.xz; do
[ -f "$file" ] || continue
printf "%s\n" "$file"
done
이는 지정된 경로의 확장자를 가진 모든 파일과 *.xz
일치하는 표준 전역 패턴입니다 . .xz
이는 [ -f "$file" ] || continue
glob이 빈 결과를 반환할 때(즉, 파일을 찾을 수 없을 때) 루프 종료를 정상적으로 처리하는 데 필요한 온전성 검사일 뿐입니다.
우연히 하위 디렉토리에서도 파일을 찾고 있다면 확장 쉘 글로빙 옵션을 활성화하여 globstar
파일 이름의 재귀적 일치를 활성화한 다음 다음을 실행하십시오.
shopt -s globstar nullglob
for file in "$ROOTPATH"/**/*.xz; do
printf "%s\n" "$file"
done
답변2
결과를 반복해서는 안 됩니다 find
. 참조하세요.찾기 결과를 반복하는 것이 왜 나쁜 습관입니까?
대신 다음 내에서 스크립트를 호출하세요 find
.
find "$ROOTPATH" -type f -name '*.xz' \
-exec sh -c 'for n; do printf "Got name %s\n" "$n"; done' sh {} +
또는 별도의 스크립트를 호출하십시오.
find "$ROOTPATH" -type f -name '*.xz' \
-exec /some/path/script.sh {} +
스크립트는 다음과 같습니다.
#!/bin/sh
for name; do
# do something with "$name"
done
이 경우 내장된 sh -c
(또는 bash -c
필요한 경우 bash
) 또는 별도의 스크립트인지 여부에 관계없이 가능한 한 많은 파일을 사용하여 호출됩니다 .xz
(파일 수가 수백 개이면 여러 번 호출될 수 있음). 루프 는 발견된 이름을 반복하여 개별 파일에 필요한 모든 작업을 수행하는 데 for name
사용할 수 있습니다 (물론 올바른 인용 포함).$name
답변3
for 루프 자체 내에서 find를 사용하십시오.
ROOTPATH="/home/user/path"
for file in `find $ROOTPATH -type f -name *.xz -print`
do
echo "file is $file"
done