eval을 사용하지 않고 파일 이름을 반복합니다.

eval을 사용하지 않고 파일 이름을 반복합니다.

쉘 스크립트에서 특정 파일 이름을 반복하려는 경우 모든 하위 디렉토리에서 "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

또한 관련:

관련 정보