마침표가 포함된 하위 디렉터리의 파일 이름을 반복하지만 경로와 파일 확장자는 제외합니다.

마침표가 포함된 하위 디렉터리의 파일 이름을 반복하지만 경로와 파일 확장자는 제외합니다.

디렉토리에 bash 스크립트가 있습니다 ./. 이 디렉토리에는 다음 과 같은 파일이 포함되어 있습니다 output.output

Alabama.txt
U.S. Virgin Islands.txt

파일을 반복 output하고 다음 출력을 인쇄하는 방법

Alabama
U.S. Virgin Islands

답변1

for pathname in output/*.txt; do
    basename "$pathname" .txt
done

basename유틸리티는 경로 이름을 가져와 모든 디렉토리 부분을 제거하고 최종 파일 이름 부분만 남깁니다. 또한 선택적 두 번째 인수로 문자열을 허용합니다. 문자열은 주어진 경로 이름의 끝에서 잘립니다.

경로 이름의 일부를 제거 하고 파일 이름 접미사를 제거하기 위해 basename모든 이름 일치에 대해 루프를 사용합니다 . 그러면 출력 파일 이름의 "줄기"만 남습니다.output/*.txtoutput/.txt

내장된 표준 매개변수 대체를 사용하여 동일한 효과를 얻을 수 있습니다.

for pathname in output/*.txt; do
    name=${pathname#output/}
    printf '%s\n' "${name%.txt}"
done

이는 로 확장된 각 경로 이름에 대해 두 개의 매개변수 대체를 수행합니다 output/*.txt. 하나는 초기 output/하위 문자열을 제거하고 두 번째는 후행 .txt하위 문자열을 제거합니다.

output디렉토리에 파일 이름 접미사가 있는 파일이 없을 위험이 있는 경우 쉘 옵션을 .txt설정할 수 있습니다 ( 사용 ). 이렇게 하면 위의 루프가 한 번만 실행되는 것을 방지할 수 있습니다( 비확장 모드 사용 ).nullglobshopt -s nullgloboutput/*.txt$pathname

dotglob디렉토리의 숨겨진 이름을 일치시키려면 쉘 옵션을 설정해야 할 수도 있습니다.

답변2

zsh대신 사용하십시오 bash:

print -rC1 -- output/*.*(N:t:r)

그중에서 olumn 에 print -rC1 --해당 매개변수 aw 를 인쇄하고 r활성화하는 데 사용되는 glob 한정자이며(일치하는 파일이 없으면 glob은 빈 상태로 확장됩니다), 파일(목차 섹션 제거) 및 확장명).1 C(N:t:r)Nnullglob:t:rtr

D 숨겨진 파일도 포함하려면 glob 한정자를 추가하세요. 이 경우 숨겨진 파일에 확장자가 있는지 확인하기 위해 *.*로 변경해야 할 수도 있습니다.?*.*

어떤 쉘이든 사용하되 GNU 구현을 사용 basename하고 관심 있는 모든 파일이 숨겨져 있지 않고 .txt확장자가 있고 output최소한 하나의 해당 파일이 포함되어 있으며 파일 목록이 너무 커서 초과할 수 없다고 가정하십시오. execve()args+env 의 크기 제한을 초과하지 않으면 다음을 수행할 수도 있습니다.

basename -as.txt output/*.txt

특히 bash(GNU 쉘) 및 GNU 구현을 사용하여 sed다음을 수행할 수도 있습니다.

(
  shopt -s dotglob nullglob
  printf '%s\0' output/?*.* |
    LC_ALL=C sed -z 's:.*/::; s/\.[^.]*$//' |
    tr '\0' '\n'
)

zsh대략적인 숨겨진 파일이 포함되어 있습니다.

관련 정보