사례 설명과 함께 사용 중인 폴더를 기반으로 다양한 검색 기준을 사용하여 파일을 반복하려고 합니다. 원래:
#!/bin/bash
case folder in
"Testordner")
search_filename=*_0_*.txt
;;
"Ordner2")
search_filename=*_65_*fg*.txt
;;
*)
;;
esac
for files in $search_filename; do
echo $files
done
나는 Last Echo의 검색 기준과 일치하는 파일 목록을 얻기를 바랐습니다. 대신 검색 기준 자체를 얻습니다.
테스트하기 위해 F="*.txt";for files in $F;do echo $files;done
bash(작동하고 파일 목록을 얻음)와 동일한 스크립트(출력을 얻음)에서 직접 시도 했습니다 *.txt
. $(..) ((..)) ${..}
작동하지 않습니다.)
왜 그런 겁니까? 어떻게 해결할 수 있나요?
기꺼이 도움을 받을 것입니다. 카를로를 기원합니다
Ubuntu 22.04LTS, KDE/플라즈마 데스크탑 v5.1.16(1)을 사용합니다. 터미널: konsole v21.12.3
답변1
Bash에서 nullglob
비활성화된 경우(일반적으로 기본값) 일치 항목이 없을 때 전역 패턴은 자체적으로 평가/확장됩니다(예: *.txt
리터럴 문자열로 평가 ). *.txt
활성화되면 nullglob
(일반적으로 스크립트에 더 적합함) 일치하는 항목이 없을 경우 전역 패턴이 빈 문자열로 평가/확장됩니다.
스크립트가 다른 디렉터리에서 실행되면 glob이 다르게 확장됩니다(물론 각 디렉터리에 동일한 파일 이름이 존재하지 않는 한).
예를 들어:
user@host:~ 0 $ touch {a,b,c}.log
user@host:~ 0 $ ls -l
total 0
-rw------- 1 user staff 0 Jul 25 10:27 a.log
-rw------- 1 user staff 0 Jul 25 10:27 b.log
-rw------- 1 user staff 0 Jul 25 10:27 c.log
user@host:~ 0 $ shopt nullglob
nullglob off
user@host:~ 1 $ echo *.log
a.log b.log c.log
user@host:~ 0 $ echo *.bak
*.bak
user@host:~ 0 $ shopt -s nullglob
user@host:~ 0 $ shopt nullglob
nullglob on
user@host:~ 0 $ echo *.log
a.log b.log c.log
user@host:~ 0 $ echo *.bak
user@host:~ 0 $
관련 없는 메모에서... 적어도 적절한 경우 명령줄 안전성과 공백 처리를 개선하는 echo "$files"
대신 의도적인 인용을 관용적으로 만드는 것을 고려해 보십시오.echo $files
예를 들어, 관심이 있다면 배열을 사용할 수도 있습니다.
#!/bin/bash -e
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
shopt -s nullglob
declare -a files=()
case "$1" in
'logs')
files=(*.log)
;;
'baks')
files=(*.bak)
;;
*)
echo 'invalid argument' 1>&2
exit 1
;;
esac
for f in "${files[@]}"; do
echo "$f"
done