하위 폴더의 특정 확장자를 가진 모든 파일에 대해 우아한 방식으로 작업을 수행하려면 어떻게합니까? *.jpg); do echo $i; done 문제 : 파일

나의 현재 최선의 방법은 :

for i in $(find . -name *.jpg); do echo $i; done

문제 : 파일 이름에서 공백을 처리하지 않습니다.

참고 : “tree”명령과 같은 그래픽 방식을 사용하고 싶습니다.



답변

정식 방법은

find . -name '*.jpg' -exec echo {} \;

(교체 \;+더 이상의 파일을 통과 echo한 번에)

또는 (GNU에 따라 다르지만 일부 BSD에도 적용됩니다) :

find . -name '*.jpg' -print0 | xargs -r0 echo

zsh :

for i (**/*.jpg(D)) echo $i

답변

더 나은 답변이 이미 제공되었습니다.

그러나 코드에서 공백이 유일한 문제는 아닙니다. 탭, 줄 바꿈 및 와일드 카드 문자도 문제입니다.

IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done

그런 다음 줄 바꿈 문자 만 문제입니다.


답변

당신이 언급 한 것은 사람들이 파일 이름을 읽으려고 할 때 직면하는 기본적인 문제 중 하나입니다. 때로는 지식이 부족하고 파일 및 폴더 구조에 대한 잘못된 개념을 가진 사람들은 ” UNIX의 모든 것이 파일 입니다”라는 사실을 잊어 버리는 경향이 있습니다. 따라서 파일 이름은 공백이있는 둘 이상의 단어로 구성 될 수 있으므로 공백도 처리해야한다는 것을 이해하지 못합니다.

솔루션 : 이 작업을 수행하는 가장 잘 알려진 방법 중 하나는 깨끗한 읽기 를 수행하는 것 입니다.

우리는 여기에있는 모든 파일을 읽고 변수에 보관합니다. 다음에 원하는 처리를 할 때 파일 이름을 공백으로 유지하는 따옴표 안에 변수를 유지해야합니다. 이것은 기본적인 방법 중 하나이지만 다른 사람들이 제공 한 다른 답변도 잘 작동합니다.

스크립트 :

 find /path/to/files/ -iname "*jpg" | \
  while read I; do
   cp -v --parent "$I" /backup/dir/
  done

여기에 나는 그들에게 경로를 제공하여 파일을 읽고 있으며 내가 읽고있는 모든 것을 변수 I 안에 보관하고 있습니다. 나는 공간을 보존하여 올바르게 처리하기 위해 처리하는 동안 나중에 인용 할 것입니다.

이것이 어떤 식 으로든 도움이되기를 바랍니다.


답변

간단히과 findbash:

find . -name '*.jpg' -exec bash -c '
    echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;

이런 식으로, 우리 $1는 기본 스크립트처럼 bash에서 고급 작업을 수행하기위한 좋은 관점을 열어줍니다.

보다 효율적인 방법 (모든 파일에 대해 새 bash를 시작하지 않아도 됨) :

find . -name '*.jpg' -exec bash -c 'for i do
    echo "treating file $i in bash, from path : ${i%/*}"
  done' -- {} +

답변

최신 버전의 bash에서는 다음 globstar옵션을 사용할 수 있습니다 .

shopt -s globstar
for file in **/*.jpg ; do
    echo "$file"
done

간단한 동작을 위해 루프를 완전히 건너 뛸 수도 있습니다.

echo **/*.jpg