쉘 스크립트에서 특정 파일 이름을 반복하려는 경우 모든 하위 디렉토리에서 "Example" 문자열로 시작하는 모든 MKV 파일과 같이 쉘 와일드카드를 통해 해당 파일 이름을 얻을 수 있습니다. make it done 을 사용하지 않고 어떻게 이를 수행할 수 있습니까 eval
?
예를 들어 다음 스크립트가 루프를 실행할 때
#!/usr/local/bin/zsh
for i in /media/mybook/Example*/; do;
t="ls \"$i\"*.mkv"
s=$(eval $t)
echo $s
done
그것을 제거할 수 있는 방법이 있나요 eval
?
답변1
왜 사용하시는지 궁금합니다 eval
. 직접 작성하시면 됩니다 s=$(ls "$i"*.mkv)
. 하지만호출이 ls
의미가 없으며 파일 이름이 손상되었습니다.. 파일을 정상적으로 반복하십시오.
for dir in /media/mybook/Example*/; do;
if ! [ -d "$dir" ]; then continue; fi
for file in "$dir"/*.mkv; do
if ! [ -e "$file" ]; then continue; fi
echo "$file"
done
done
"$dir"
디렉터리 이름의 특수 문자(예: 공백)가 그대로 유지되도록 큰따옴표 안에 있지만 *
따옴표 외부에는 와일드카드로 처리된다는 점에 유의하세요 .
라인은 continue
와일드카드 불일치의 특별한 경우를 건너뛰는 것입니다. sh에서 와일드카드가 일치하지 않으면 그대로 유지되므로 for
한 요소가 리터럴인 이름 목록이 표시됩니다 /media/mybook/Example*/
(외부 루프의 경우). 일부 셸(ksh, bash, zsh)에는 이를 방지하는 방법이 있습니다(예: bash).
shopt -s nullglob
for dir in /media/mybook/Example*/; do;
for file in "$dir"/*.mkv; do
echo "$file"
done
done
파일만 처리하고 디렉터리에 대해 아무 작업도 수행할 필요가 없다면 두 개의 중첩 루프를 사용할 필요가 없습니다.
for dir in /media/mybook/Example*/*.mkv; do
if ! [ -e "$file" ]; then continue; fi
echo "$file"
done
이러한 모든 조각은 Example*
하위 디렉터리의 파일이 아닌 디렉터리 자체 내의 파일에서 작동합니다. 디렉터리를 재귀적으로 탐색하려면 다음을 참조하세요.코살로난다의 답변.
답변2
사용 find
:
find /media/mybook/Example*/ -type f -name '*.mkv' -print
하위 디렉터리로 재귀적으로 이동하지 않으려면 -maxdepth 1
앞에 추가하세요.-type f
또는 직선 쉘 루프(수천 개의 파일이 있는 경우 작동하지 않음)를 사용하고 첫 번째 하위 디렉토리 레벨만 보려고 한다고 가정합니다.
for pathname in /media/mybook/Example*/*.mkv; do
printf '%s\n' "$pathname"
done
하위 디렉토리로 재귀하려면 zsh
또는 bash
해당 globstar
쉘 옵션 세트를 사용하십시오(역시 수천 개의 파일에는 적합하지 않음).
for pathname in /media/mybook/Example*/**/*.mkv; do
printf '%s\n' "$pathname"
done
관련된:
도착하다하다경로명이 있는 것:
그리고 find
:
find /media/mybook/Example*/ -type f -name '*.mkv' -exec sh -c '
for pathname do
# Use "$pathname" here
done' sh {} +
... sh -c
분명히 변경될 수 있거나 bash -c
이러한 zsh -c
쉘의 특별한 기능을 사용해야 하는 경우.
관련된:
쉘 루프를 사용하십시오:
for pathname in /media/mybook/Example*/*.mkv; do
# Use "$pathname" here
done
또한 관련: