지금까지 2시간 동안 zsh 스크립팅을 배웠는데 막혔습니다. 공백이 있을 수 있는 파일 목록을 찾아보고 싶습니다. 나는 zsh인 한 아래 예제에 대해 완전히 다른 접근 방식을 사용할 수 있습니다. 왜냐하면 zsh는 제가 스크립트를 작성하려는 것이 아니라 제가 작업 중인 것이기 때문입니다.
files=(`ls`)
for f in $files; do
print $f
done
분명히 나는 단지 를 다시 만드는 것이 아니라 루프가 반복될 때마다 전체 파일 이름을 캡처 ls
하고 싶습니다 .$f
답변1
첫째, 사용법은 ls
단지 예일 뿐이라고 가정합니다. ls
모호하기 때문에 어떤 쉘에서도 출력을 구문 분석 할 수 없습니다 . 읽다ls(1)의 출력을 분석하면 안되는 이유이것이 당신에게 뉴스라면. 모든 셸에서 파일 목록을 얻으려면 files=(*)
.
zsh에서는 다른 쉘과 마찬가지로 결과는 다음과 같습니다.명령 대체공백 문자에서 단어로 분할합니다(보다 정확하게는 값을 기준으로 함 IFS
). (다른 쉘과 달리 명령 대체 결과는 zsh의 globbing에 영향을 받지 않습니다.) 따라서 명령의 출력이 다음과 같을 ls
경우
hello world
wibble
그런 다음 , 및 3개의 요소를 포함하도록 배열을 files=($(ls))
설정합니다 .files
hello
world
wibble
명령 대체를 큰따옴표로 묶으면 분할이 수행되지 않습니다. 사용자 정의 분할을 수행할 수 있습니다.매개변수 확장 플래그. 이 @
플래그를 사용하여 분할 결과가 배열임을 나타냅니다(이상하게도 확장을 큰따옴표로 유지해야 합니다. 즉, "${(@)…}"
큰따옴표로 묶인 문자열도 여러 단어로 확장됩니다). 분할의 경우 쉼표로 분할 s
과 같은 플래그를 사용하십시오 "${(@s:,:)…}"
. 이 f
플래그는 줄 바꿈에서만 분할됩니다.
files=("${(@f)$(ls)}")
일반적으로 배열을 반복하는 올바른 방법은 빈 요소를 for f in $files[@]
제거하는 것 입니다 $files
(여기서는 요소가 비어 있지 않으므로 이는 중요하지 않습니다).
print $f
a로 시작하고 백슬래시를 확장하면 $f
스위치로 해석됩니다. 문자열 뒤에 개행 문자를 원하지 않으면, 또는 를 사용하세요.-
$f
print -r -- $f
print -rn -- $f
답변2
zsh에서는 기본적으로 단어 분리를 수행하지 않는 셸 확장을 사용할 수 있습니다. 노력하다
for f in /path/to/files/*; do
print ${f}
done