나는이 편지를 쓰고 싶다. /bin/sh
와일드 카드와 일치하는 모든 파일을 처리하는 쉘 스크립트. 하나 이상의 일치하는 파일을 처리하기 쉽습니다. 그러나 일치하는 파일이 0 개 인 경우를 처리하는 것이 좋지 않습니다.
분명한 구조는 다음과 같습니다.
#!/bin/sh
for f in *.ext; do
handle "$f"
done
어디에 *.ext
쉘이 파일 경로와 비교하는 하나 이상의 표현식 일 수 있습니다. handle
기존 파일에 대한 경로가 주어지면 올바르게 실행되는 쉘 명령이지만 파일에 맵핑되지 않는 경로를 제공하면 실패합니다. (이 질문을 유발하는 경우, 그들은 *.flac
과 ffmpeg
,하지만 그건 중요하지 않다고 생각합니다.)
일치하는 파일이있는 경우 foo.ext
, bar.ext
,이 스크립트는 다음을 수행합니다.
handle "foo.ext"
handle "bar.ext"
예상대로 그러나, 아니 일치하는 파일이면이 스크립트는 다음과 같은 오류 메시지를 표시합니다.
handle: *.ext: No such file or directory
나는 이것이 왜 일어나는 지 이해할 수 있다고 생각합니다. 세게 때리다 맨 페이지 (나는 /bin/sh
또한) "다음 단어 목록 in
항목 목록을 생성합니다. ... 다음 항목을 확장하면 결과가 빈 목록으로 나타나고 명령이 실행되지 않고 반환 상태는 0입니다. "분명히 *.ext
"확장 됨", 결과 목록에는 다음이 포함됩니다. *.ext
, 빈 목록 대신. 그러나 그것은 그 일을 어떻게 멈추게 하는지를 설명하지 못합니다.
(업데이트 : sh (1)
가보 프로젝트의 맨 페이지 Bourne Shell에 대해 설명합니다. sh
, 나중에 Bourne Again 쉘 bash
. 아래에 파일 이름 생성 패턴과 일치하는 파일 이름이 없으면 단어는 변경되지 않습니다. "라고 분명하게 말합니다. 왜 sh
잎을 *.ext
패턴 목록에 있습니다.)
작고, 관용적 인 방법으로이 루프를 작성하여 일치하는 파일이없는 경우 오류없이 0 번 실행되지만 일치하는 각 파일에 대해 한 번 실행됩니다. 더 나은 방법은 다음과 같은 여러 패턴을 사용하는 것입니다.
for f in *.ext1 special.ext1 *.ext2; do ...
나는 문법 호환을 선호한다. /bin/sh
, 이식성. 필자는 Mac OS X 10.11.6을 사용하고 있지만, 유닉스와 비슷한 OS에서 작동하는 구문을 기대하고 있습니다.
그런 루프를 작성하기 위해 서투른, 비 관용적 인 두 가지 방법을 생각해 냈습니다. 만약 내가 좋은 답변을 즉시 얻지 못한다면, 나는 그 답을 기록으로 남길 것입니다.
/bin/sh
, 그러나 그것은 절대적이지 않습니다. "bash로 전환 한 다음이 작업을 수행하십시오"라는 형식의 대답이 도움이된다고 생각합니다. 그것은 "sh에서 그것을하는 방법이 있습니다"라고 말하는 것만 큼 좋지는 않을 것입니다. 그러나 아마 그러한 대답은 존재하지 않을 것입니다.
nullglob
루프가 실행되지 않게됩니다.