특정 디렉터리의 모든 파일을 반복적으로 수집

특정 디렉터리의 모든 파일을 반복적으로 수집

확장명을 가진 많은 디렉토리가 있는 프로젝트가 있습니다 .strings.

이러한 파일은 여러 언어로 현지화된 버전입니다.

예를 들어, 이름이 같은 파일이 3개 있지만 각 파일은 , 또는 MyView.strings와 같은 지역화된 디렉터리에 있을 수 있습니다 . 프로젝트 구조에는 이러한 디렉터리가 수백 개 있습니다.en.lprojit.lprojpt-PT.lproj

저는 이러한 모든 파일이 있는 디렉토리를 언어별로 나열하는 bash 스크립트를 만들고 있습니다.

en.lproj예: 디렉터리 구조를 스캔하고 해당 구조에 있을 수 있는 모든 디렉터리를 찾고 해당 디렉터리 내에 있는 모든 파일의 전체 경로를 나열하고 싶습니다.

그 문제에 대해 이와 같은 명령은 터미널 창에서 작동합니다

find . -type d -name "en.lproj" -print  

그러나 나중에 bash 스크립트에서 열거하기 위해 그러한 명령의 결과를 배열에 저장하는 방법은 무엇입니까?

나는 이것을 시도했다

result=($(find . -type d -name "en.lproj" -print))

그러나 경로에 공백이 포함되어 있기 때문에 해당 공간에서 배열이 손상되고 결과는 공백이 있든 없든 각 행이 경로인 배열이 될 것으로 예상됩니다.

저는 macOS BigSur를 사용하고 있습니다.

답변1

명령의 출력을 배열로 저장하려면 다음이 필요합니다.

array=( $(command) )

그러나 셸은 값을 기준으로 명령 결과를 분할합니다 $IFS. 이는 일반적으로 공백, 탭 및 줄 바꿈으로 설정되므로 이러한 문자가 포함된 파일 이름을 반환하는 명령을 사용하는 경우 배열은 이름의 각 부분에 대해 별도의 요소를 갖게 됩니다. 표시하려면:

$ touch 'a file with spaces'
$ ls
'a file with spaces'

$ array=( $( find . -type f) )

$ for f in "${array[@]}"; do echo "FF: $f"; done
FF: ./a
FF: file
FF: with
FF: spaces

귀하의 경우 모든 파일에 공백이 없는 간단한 이름이 있으면 다음을 수행할 수 있습니다(필수는 아니며 -print이것이 기본 작업입니다).

files=( $(find . -type d -name "en.lproj") )

그러나 안전을 위해 $IFS이 명령을 재정의하여 모든 파일 이름에 대해 작동하도록 할 수 있습니다(줄바꿈이 포함된 파일 이름 제외).

$ IFS=$'\n' array=( $( find . -type f) )
$ for f in "${array[@]}"; do echo "FF: $f"; done
FF: ./a file with spaces

개행 문자를 포함하여 임의의 파일 이름을 처리할 수 있어야 하는 경우 구분 기호를 사용하여 null로 설정하거나 (이식 가능하지는 않지만 GNU 및 BSD에서 지원하므로 Mac에서의 작업에 있어야 함) mapfile사용할 수 있습니다. find) 개행 대신 빈 구분 기호를 사용하여 결과를 인쇄하는 옵션 -print0:find

mapfile -d '' array < <(find . -type f -print0)

이는 모든 유형의 파일을 처리합니다.

$ touch 'a bad
file'
$ ls
'a bad'$'\n''file'  'a file with spaces'

$ mapfile -d '' array < <(find . -type f -print0)
$ for f in "${array[@]}"; do echo "FF: $f"; done
FF: ./a file with spaces
FF: ./a bad
file

관련 정보