Bash 와일드카드는 특정 확장자를 가진 파일을 제외한 모든 파일과 일치하며 점 문자가 포함된 파일 이름에 작동합니다.

Bash 와일드카드는 특정 확장자를 가진 파일을 제외한 모든 파일과 일치하며 점 문자가 포함된 파일 이름에 작동합니다.

저는 오디오 파일로 작업을 하고 있습니다. 대부분은 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.mp3foo.뒤에는 다음이 있으므로 일치합니다 bar.mp3.아니요mp3.

!(*.mp3)여기에서 로 끝나지 않는 모든 항목과 일치 합니다 .mp3.

.이름에 적어도 하나 (숨겨진 파일로 만드는 선행 파일 제외)가 포함되어 있지만 로 끝나지 않는 파일을 일치시키려면 .mp3다음을 수행할 수 있습니다 !(*.mp3|!(*.*)).

어쨌든 , bash.​--enable-extended-glob-defaultshopt -s extglob

답변2

게다가GLOBIGNORE변수:

GLOBIGNORE변수를 사용하여 패턴과 일치하는 파일 이름 세트를 제한할 수 있습니다. GLOBIGNORE설정된 경우 GLOBIGNORE이러한 패턴 중 하나와 일치하는 각 일치하는 파일 이름이 일치 목록에서 제거됩니다. 이 옵션을 설정 하면 대소문자에 관계없이 nocaseglobin의 패턴과 일치하는 항목을 검색합니다 . GLOBIGNORE설정되고 비어 있지 않으면 filename ...은 항상 무시됩니다. GLOBIGNORE그러나 GLOBIGNOREnull이 아닌 값으로 설정하면 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

  • -Egrep 확장(정규식 사용)

정규식 설명:

  • .*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

https://stackoverflow.com/questions/18278990/easiest-way-to-check-for-file-extension-in-bash/18280350

관련 정보