폴더의 모든 파일을 반복해야 하는 bash 스크립트가 있습니다.
이것은 내 현재 기능입니다.
function listDir(){
for file in "$1"/*;
do
echo $file
done
}
문제는 숨겨진 파일이나 폴더(.hiddenFile)가 나열되지 않는다는 것입니다. 어떻게 해야 하나요?
Kusalananda의 답변을 바탕으로 다음과 같이 스크립트를 편집했습니다.
listDir () {
for file in $(find "$1" -maxdepth 1 -mindepth 1 -print);
do
echo $file
done
}
그러나 이름에 공백이 있는 폴더에는 이 기능이 작동하지 않습니다. 파일 이름을 나열하는 것뿐만 아니라 파일 이름으로 다른 작업을 수행하려면 for 루프가 필요합니다.
이 문제를 어떻게 해결할 수 있나요?
답변1
기본적으로 쉘 *
글로빙 패턴은 숨겨진 이름과 일치하지 않습니다.
에서는 bash
쉘 옵션을 활성화하여 이를 달성할 수 있습니다 dotglob
. 당신은 이런 일을 하곤 해요 shopt -s dotglob
.
$file
또한 코드에서 확장을 인용 해야 합니다 . 그렇지 않으면 셸이 해당 값에 대해 토큰화 및 파일 이름 글로빙을 수행합니다.
listDir () (
shopt -s dotglob
for pathname in "$1"/*; do
printf '%s\n' "$pathname"
done
)
위 루프에서 다른 작업을 수행 해야 하는 경우 $pathname
변수 확장을 큰따옴표로 묶어야 합니다 "$pathname"
. 이렇게 하면 다양한 문자가 포함된 파일 이름에 대해 함수가 작동하게 됩니다.
이 함수를 호출할 때 공백이 포함된 경우 디렉터리 이름을 인용해야 합니다.
listDir "my directory/here somewhere"
두 가지 대안(파일만 나열하면 된다고 가정):
listDir () (
shopt -s dotglob
printf '%s\n' "${1:-.}"/*
)
함수 본문을 (하위 쉘)로 묶어서 호출 쉘에 쉘 옵션이 설정되지 않았 ( ... )
는지 확인합니다 .dotglob
just 대신 in을 사용하여 ${1:-.}
디렉토리(또는 빈 문자열)가 제공되지 않으면 $1
(현재 디렉토리)를 나열할 기본 디렉토리로 사용합니다..
printf
형식 문자열의 자리 표시자보다 더 많은 인수가 제공되면 유틸리티는 해당 형식 문자열을 재사용합니다. 여기서는 이 사실을 사용하여 파일 이름을 개행으로 구분된 목록으로 인쇄합니다.
를 사용하세요 . find
다음은 필요하지 않습니다 dotglob
.
listDir () {
find "${1:-.}" -maxdepth 1 -mindepth 1 -print
}
find
사용하는 동안 발견된 파일에 대해 다른 작업을 수행하려면아니요루프의 출력을 시험해 보십시오 find
. 대신 다음을 사용하십시오 -exec
.
listDir () {
find "${1:-.}" -maxdepth 1 -mindepth 1 -exec sh -c '
for pathname do
# code that does something with "$pathname"
done' sh {} +
}
관련된:
답변2
bash에 태그를 지정했으므로 배열을 사용할 수도 있습니다.
shopt -s dotglob
files=( "$1"/* )
그런 다음 인쇄하거나 작업할 수 있습니다.
printf "File: %s\n" "${files[@]}"
또는
rm "${files[@]}"
또는
for f in "${files[@]}"; do mv "${f}" "renamed-${f}"; done