여러 개의 하위 디렉터리가 있는 디렉터리가 있습니다. 하위 디렉토리를 하나씩 반복하고 있습니다. 그런 다음 CD를 사용하여 디렉토리를 변경합니다. 해당 하위 디렉터리에 .partial 확장자를 가진 파일이 있는 경우 파일 이름을 저장합니다. 그런 다음 하위 디렉터리 이름과 파일 이름의 일부를 인쇄해야 합니다. 나는 이런 것을 썼다.
for f in *
do
if [ -d "$f" ]; then
cd "$f"
a=$(find ./ -name "*.partial")
if [ -e "$a" ];then
echo -e "$f" "\t" "$a"
fi
cd ..
fi
done
find
문제는 내가 원하지 않는 추가 하위 디렉토리에서 파일 확장자를 반복적으로 찾는다는 것입니다 . .partial
현재 디렉터리로만 제한하려면 어떻게 해야 합니까?
답변1
.partial
현재 디렉토리와 관련된 각 파일의 전체 경로 이름 만 출력합니다 .
printf '%s\n' ./*/*.partial
일치하는 항목이 없는 경우 nullglob
쉘 옵션을 설정하면 패턴 자체가 출력되지 않으며(빈 줄은 여전히 출력됨) 숨겨진 이름도 일치합니다.bash
dotglob
다음은 이러한 경로 이름을 디렉터리 경로와 파일 이름 부분으로 나눕니다.
for name in ./*/*.partial; do
[ -f "$name" ] && printf '%s\t%s\n' "${name%/*}" "${name##*/}"
done
그러면 현재 디렉토리의 하위 디렉토리에 있는 .partial
모든 이름에 대한 하위 디렉토리 이름과 파일 이름이 인쇄됩니다..partial
에서는 bash
숨겨진 이름도 일치시켜야 하는 경우 쉘 옵션을 설정해야 할 수도 있습니다.dotglob
dirname
이 두 가지 인수 대체는 및 다음을 호출하여 수행할 수 있습니다 basename
.
for name in ./*/*.partial; do
[ -f "$name" ] && printf '%s\t%s\n' "$(dirname "$name")" "$(basename "$name")"
done
하위 디렉터리 이름을 한 번만 인쇄하는 위의 변형입니다(이렇게 하려면 디렉터리 경로를 제거하고 각 위치 인수에 대한 파일 이름을 유지하는 bash
쉘과 같은 인수 확장이 필요합니다).${*%%*/}
IFS=$'\t'
for dirname in ./*/; do
set -- "$dirname"/*.partial;
[ -f "$1" ] && printf '%s\t%s\n' "$dirname" "${*##*/}"
done
이는 각 하위 디렉터리를 반복하고 *.partial
각 하위 디렉터리의 와일드카드 패턴을 확장합니다. 첫 번째 일치 항목이 일반 파일(또는 파일에 대한 링크)인 경우 하위 디렉터리 이름을 인쇄하고 그 뒤에 패턴과 일치하는 이름을 인쇄하고 디렉터리 경로를 제거합니다.
답변2
이 find
유틸리티는 다음 옵션을 지원합니다.-maxdepth
-max 깊이 레벨
시작점 아래의 디렉토리로 내려가는 가장 높은 레벨(음수가 아닌 정수) 레벨입니다. -maxlength 0은 시작점 자체에만 테스트와 작업을 적용한다는 의미입니다.
find
특정 디렉터리로 제한하려면 options 를 추가하세요 -maxdepth 1
.
깊이 2의 모든 일반 파일을 나열하려고 하면 *.partial
출력이 질문의 것과 유사합니다. 다음 명령을 시도해 볼 수 있습니다.
find . -mindepth 2 -maxdepth 2 -type f -name '*.partial' -printf '%h\t./%f\n'
이는 다음과 유사한 출력을 제공할 수 있습니다.
./b ./file2.partial
./b ./file3.partial
./a ./file1.partial
답변3
GNU가 있다면 find
다음과 같이 할 수 있습니다
for dir in *
do
files=$(find "$dir" -maxdepth 1 -type f -name '*.partial' -printf "%f\n" | xargs)
[[ -n "$files" ]] && printf "%s\t%s\n" "$dir" "$files"
done
GNU가 없다면 find
효율성을 희생하면서 다음과 같이 에뮬레이트할 수 있습니다.-printf '%f\n'
for dir in *
do
files=$(cd "$dir" && find . -maxdepth 1 -type f -name '*.partial' -print | sed 's!^./!!' | xargs)
[[ -n "$files" ]] && printf "%s\t%s\n" "$dir" "$files"
done
두 솔루션 모두 줄 바꿈이나 이상한 인쇄 문자가 있는 파일을 처리하지 않습니다. 하지만 디렉터리의 파일을 한 줄에 나열하면 이상한 파일 이름이 생기지 않기를 바랍니다. 쉘이 이를 이해하지 못한다면 [[ ... ]]
이중 괄호를 단일 괄호로 바꾸십시오 [ ... ]
.