우리 모두 알고 있듯이 ls 구문 분석의 결과는 다음과 같습니다.일반적으로 나쁜 생각한 가지 해결책은 ls 대신 globbing을 사용하여 디렉터리의 파일을 "안전하게" 반복하는 것입니다.
for path in /path/to/search/*; do
...
# Do more filtering
...
echo "$path"
done
이 함수는 전역 일치의 일부 결과를 추가로 필터링하고 나머지 경로를 출력합니다.
하지만 이 논리를 다른 곳에서 재사용하려면 함수를 통해 해당 출력을 안전하게 사용하고 반복할 수 있습니까?
function myglob() {
for path in /path/to/search/*; do
...
# Do more filtering
...
echo "$path"
done
}
function myExample() {
results=$(myglob)
for i in "$results"; do
echo "$i"
done
}
아니면 항상 전역 논리를 복사하고 내부 논리를 약간 변경해야 합니까?
답변1
아니요, 표시된 루프 출력은 문제를 정확하게 복제하고 파일 이름의 백슬래시를 해석할 가능성을 ls
추가하기 때문에 재사용할 수 없습니다.echo
대조적으로 배열과 이름 참조가 있는 쉘 언어를 사용하는 경우( bash
4.3+에서와 같이) 이 작업을 약간 다르게 수행할 수 있습니다.
myglob () {
declare -n list="$1"
list=( /path/to/search/* )
}
myexample () {
local results=()
myglob results
for pathname in "${results[@]}"; do
printf '%s\n' "$pathname"
done
# or shorter, just
# printf '%s\n' "${results[@]}"
}
여기서 함수는 이름 참조 변수인 myglob
변수의 이름을 사용합니다 . list
이는 모든 사용이 list
실제로 명명된 변수를 사용한다는 것을 의미합니다. 이 함수는 단지 glob을 확장하고 list
마치 배열인 것처럼 그 안에 결과를 저장합니다 .
그런 다음 함수 myexample
는 myglob
문자열을 사용하여 호출됩니다 results
. 따라서 list
의 변수는 myglob
해당 results
변수를 참조하고 확장된 패턴을 저장합니다.
그런 다음 함수는 results
항목 배열로 계속 사용됩니다.
myglob
필터링이 필요한 경우 :
myglob () {
declare -n list="$1"
list=()
for pathname in /path/to/search/*; do
# decide whether to use "$pathname" or not
# then, if it is to be used,
list+=( "$pathname" )
done
}
즉, 호출자에게 항목을 반환하려면 확장된 패턴을 반복하고 항목을 목록에 추가하세요.