현재 저는 생성 날짜 순서대로 디렉터리의 특정 파일을 반복하도록 되어 있는 bash 스크립트를 작성 중입니다. 이를 위해 다음을 사용합니다(대신 실제 코드 사용 echo
).
for i in $(ls -tr)
do
echo $i
done
대부분의 경우 잘 작동합니다.
하지만 이제 스크립트를 손상시키는 파일 형식을 발견했습니다: aha_-_a ()a.txt
.
파일 이름에는 공백과 여는 괄호 "("가 포함되어 있는데, 이는 개행을 실행하는 것처럼 보입니다. 결과는 다음과 같습니다.
aha_-_a
()a.txt
하지만 다음과 같아야 합니다.
aha_-_a ()a.txt
원하는 동작을 얻는 방법을 알고 있나요?
답변1
인용을 해제하면 $(ls -tr)
확장 시 분할+glob이 호출됩니다.
분할은 $IFS
문자(기본값은 SPC, TAB 및 NL)를 기준으로 수행되며 glob 부분은 문자에서 와일드카드를 찾고 해당 패턴과 일치하는 파일을 확장하려고 시도합니다.
ls
여기서는 실제로 glob 부분을 수행하지 않고 NL 문자로 출력을 분할하려는 것처럼 보입니다 . 따라서 다음과 같아야 합니다.
IFS=$'\n' # split on NL only
set -o noglob # disable the glob part
for f in $(ls -tr); do
printf '%s\n' "$f"
done
이는 SPC 문자가 포함된 파일에 대해 정상적으로 작동합니다. 그러나 파일 이름에 NL 문자가 있으면 여전히 작동하지 않습니다.
여기서는 zsh
다음으로 전환하여 수행하는 것이 가장 좋습니다.
for f in *(NOm); do
printf '%s\n' "$f"
done
여기서 glob 한정자를 사용하는 것처럼( (for ) 일치하는 파일이 없는 경우 오류를 방지하는 것처럼) *
현재 디렉터리에서 숨겨지지 않은 모든 파일로 확장되고 기간을 기준으로 역순으로 정렬됩니다 .ls -rt
Om
N
nullglob
또는 GNU가 있는 경우 다음을 ls
수행하십시오 bash
.
eval "files=($(ls --quoting-style=shell-always -rt))"
for f in "${files[@]}"; do
printf '%s\n' "$f"
done