Powershell에서는 다음과 같은 작업을 수행하는 데 익숙합니다.
> $python_files = get-childitem *.py
> echo $python_files[0]
get-childitem
두 번째 명령을 사용 하면 배열과 유사한 객체가 반환되므로 첫 번째 파일을 추출할 수 있습니다 .
Bash에서는 다음 내용이 거의 동일하다는 것을 알고 있습니다.
> test=$(find . -iname '*.py')
그런데 첫 번째 항목을 얻지 못해서 문자열 같은 객체가 반환되는 줄 echo $test[0]
알았어요 .find
명령에서 첫 번째 항목을 가져오는 일반적인 방법이 있습니까 find
? 범용이란 명령 독립적이거나 grep
.
답변1
Bash에서는 다음 내용이 거의 동일하다는 것을 알고 있습니다.
test=$(find . -iname '*.py')
그러나
echo $test[0]
첫 번째 항목을 얻지 못했기 때문에 find가 문자열과 같은 객체를 반환한다고 가정합니다.
일부 값의 경우 "대략"입니다. 실제로 "대략" 값은 매우 대략적입니다.
파이프와 명령 대체는 파일과 같은 객체인 명령의 출력(표준 출력, stdout)을 읽는 데 의존합니다(물론 검색할 수 없습니다(예: 무작위 액세스)). 이것은 바이트 스트림입니다. 다음과 같이 직렬화되지 않는 한 데이터 구조의 전송을 허용하지 않습니다.바이트 시퀀스.
당신이 원하는 것은 파일 이름을 한 줄에 하나씩 인쇄하도록 test=$(find . -iname '*.py')
요청한 find
다음 쉘이 이를 string 으로 변수에 읽어들이도록 하는 것입니다 test
. 변수에는 다음과 같은 내용이 포함됩니다 hello.txt<newline>there.txt
. 이는 어느 정도 괜찮지만 쉘 배열이 아니므로 색인을 생성할 수 없으며 파일 이름에 개행 문자가 포함되어 있으면 중단됩니다. (또한 파일 이름에 공백이 포함되어 있으면 깨질 것입니다 for f in $(find...)
. 이는 다른 시나리오이고 단어 분리가 관련되어 있기 때문입니다.)
find
Bash에서 배열 의 출력을 읽으려면 readarray
프로세스 대체(이것 <(...)
)를 사용할 수 있습니다.
readarray -d '' -t files < <(find ... -print0)
printf '%s\n' "Third element of array is '${files[2]}'"
-print0
find
NUL 바이트로 출력의 각 파일 이름을 종료하도록 지시합니다 . 이는 파일 이름에 나타날 수 없는 유일한 바이트이기 때문에 명시적 직렬화에 작동합니다. NUL을 구분 기호로 예상하도록 -d ''
지시합니다 . readarray
배열 인덱스는 다음에서 시작됩니다.영Bash에서 (참조http://mywiki.wooledge.org/BashGuide/Arrays).
(이식성에 관해서: 모든 쉘이 어레이를 지원하는 것은 아니며 zsh는 지원하지만 약간 다르게 작동합니다. -print0
또한 표준은 아니지만 널리 지원됩니다.)
또는 쉘 glob과 일치하는 파일 목록을 원하는 경우:
files=( *.py )
(일치하는 파일이 없는 경우 bash
이 옵션을 설정하지 않으면 호출된 요소를 얻게 됩니다.)*.py
nullglob
globstar
여기서는 또는 dotglob
다른 옵션을 사용할 수 있지만 extglob
, 사용 가능한 옵션은 물론 쉘에 따라 다르며 find
제공된 옵션과 다릅니다.