
저는 오디오 파일로 작업을 하고 있습니다. 대부분은 mp3 파일이지만 전부는 아닙니다. 이제 mp3가 아닌 파일이나 확장자가 없는 파일에 대해 일부 명령을 실행하고 싶습니다 .mp3
.
나는 정규 표현식에는 능숙하지만 파일 글로빙에는 그다지 능숙하지 않다고 생각하며 이는 예상치 못한 방식으로 미묘한 차이를 만듭니다.
나는 Bash가 이 작업을 수행할 수 있는 "확장 와일드카드"를 가지고 있다는 다른 SO & SE 답변을 둘러보고 배웠습니다.
file ../foo/bar/*.!(mp3)
하지만 내 파일 이름 중 일부에는 파일 확장자를 구성하는 점 외에 점이 포함되어 있습니다.
../foo/bar/Naked_Scientists_Show_19.10.15.mp3
../foo/bar/YWCS_ep504-111519-pt1_5ej4_41cc9320.mp3_42827d48daefaa81ec09202e67fa8461_24419113.mp3
../foo/bar/eLife_Podcast_19.09.26.mp3
../foo/bar/gdn.sci.080428.bg.science_weekly.mp3
글로벌 매치는 마지막 포인트가 아닌 첫 번째 포인트부터 시작되는 것 같습니다. 문서를 살펴봤지만 정규식만큼 강력하지는 않은 것 같습니다. 그러나 나는 *nix 쉘을 다루는데 많은 시간을 보내지 않았기 때문에 모든 것을 실제로 이해하지는 못했습니다.
Bash 와일드카드를 통해 이 작업을 수행할 수 있는 방법이 없나요? 그렇지 않다면 찾기나 다른 도구를 사용하여 동일한 결과를 얻는 방법을 아는 것이 여전히 가치가 있습니다.
답변1
*.!(mp3)
foo.bar.mp3
그 foo.
뒤에는 다음이 있으므로 일치합니다 bar.mp3
.아니요mp3
.
!(*.mp3)
여기에서 로 끝나지 않는 모든 항목과 일치 합니다 .mp3
.
.
이름에 적어도 하나 (숨겨진 파일로 만드는 선행 파일 제외)가 포함되어 있지만 로 끝나지 않는 파일을 일치시키려면 .mp3
다음을 수행할 수 있습니다 !(*.mp3|!(*.*))
.
어쨌든 , bash
.--enable-extended-glob-default
shopt -s extglob
답변2
게다가GLOBIGNORE
변수:
쉘
GLOBIGNORE
변수를 사용하여 패턴과 일치하는 파일 이름 세트를 제한할 수 있습니다.GLOBIGNORE
설정된 경우GLOBIGNORE
이러한 패턴 중 하나와 일치하는 각 일치하는 파일 이름이 일치 목록에서 제거됩니다. 이 옵션을 설정 하면 대소문자에 관계없이nocaseglob
in의 패턴과 일치하는 항목을 검색합니다 .GLOBIGNORE
설정되고 비어 있지 않으면 filename.
및..
은 항상 무시됩니다.GLOBIGNORE
그러나GLOBIGNORE
null이 아닌 값으로 설정하면dotglob
쉘 옵션을 활성화하는 효과가 있으므로 ' '로 시작하는 다른 모든 파일 이름이.
일치합니다. ''로 시작하는 파일 이름을 무시하는 이전 동작을 얻으려면.
'.*
'을(를) 설정하십시오. 이 옵션은GLOBIGNORE
설정되지 않은 경우dotglob
비활성화됩니다 .GLOBIGNORE
$ touch a.b.mp3 .c.mp3 foo.tgz .bar
$ echo *
a.b.mp3 foo.tgz
$ shopt -s extglob; echo *.!(mp3)
a.b.mp3 foo.tgz
$ GLOBIGNORE='*.mp3'; echo *
.bar foo.tgz
답변3
내가 생각할 수 있는 가장 간단한 방법은 다음과 같습니다.
find ${path-to-folder} -type f | grep -vE ".*\.mp3$"
폴더에서 모든 파일을 찾아 역확장 grep으로 파이프할 수 있습니다.
특정 위치에 있는 모든 파일 찾기
find ${path-to-folder} -type f
grep을 되돌리고 정규식을 사용하여 확장자로 필터링
grep -vE ".*\.mp3$"
Grep 플래그:
-v
역방향 grep-E
grep 확장(정규식 사용)
정규식 설명:
.*
0부터 가능한 모든 문자까지의 문자 수를 나타냅니다.\.
실제 포인트 찾기mp3
확장을 형성하는 문자열의 경우$
생산 중단을 나타냅니다.
답변4
귀하의 경우에는 적합하지 않을 수도 있지만 순수 함수로 함수를 생성한 다음 확장 을 Bash
매개변수로 전달하는 방법을 알고 싶습니다 . bashrc
미래에는 아래처럼
따라서 기본적으로 우리가 하는 일은 원하는 확장을 정규식으로 검사하는 것입니다.
for file in *; do
if [[ $file =~ \.mp3$ ]]; then
echo $file
fi
done
함수로 구현: 현재 디렉터리에서 특정 확장자를 가진 모든 파일을 출력합니다.
getFileByExt(){
local extension="$1"
if (( $# == 1 )); then
for file in *; do
if [[ $file =~ \.$extension$ ]]; then
echo $file
fi
done
else
echo "Usage: ${FUNCNAME[0]} <extension>"
## If run from bashrc, return the name of function
fi
}
이제 확장자가 .인 모든 파일을 얻으려면 mp3
다음과 같이 간단합니다.
getFileByExt mp3
특정 확장자가 없는 파일 가져오기: 특정 확장자가 없는 현재 디렉터리의 모든 파일이 출력됩니다.
getFileWithoutExt(){
local extension="$1"
if (( $# == 1 )); then
for file in *; do
if [[ ! $file =~ \.$extension$ ]]; then
echo $file
fi
done
else
echo "Usage: ${FUNCNAME[0]} <extension>"
fi
}
mp3
마찬가지로 확장자 없이 파일을 얻으려면 다음을 수행하십시오.
getFileWithoutExt mp3
자세한 내용은:
https://stackoverflow.com/questions/407184/how-to-check-the-extension-of-a-filename-in-a-bash-script