여러 디렉터리 수준을 안정적으로 탐색하는 명령줄

여러 디렉터리 수준을 안정적으로 탐색하는 명령줄

질문하신 것과 같은 문제가 있습니다 파일 확장자가 누락된 음악 파일 이름 바꾸기 @Gilles가 제공한 스크립트는 매우 교육적이었지만 불행히도 예상한 대로 작동하지 않았습니다. 내가 찾고 있던 것은 "/path/to/music/directory/" 아래의 모든 수준에서 모든 하위 디렉터리에 있는 확장자가 없는 모든 음악 파일에 파일 확장자를 추가하는 스크립트였습니다. 제안된 명령줄 매개변수

/path/to/music/directory/{**/,}*

스크립트가 "/path/to/music/directory/" 한 수준 아래 하위 디렉터리의 모든 파일을 통과하지만 그 아래 수준은 통과하지 않도록 합니다. "directory/" 아래의 모든 수준에 있는 모든 파일을 탐색하려면 어떤 명령줄 매개변수를 사용해야 합니까?

또한

{**/,}* 

부분.

그런데, 원래 답변에 관심이 있는 분들을 위해. 줄을 변경한 후에 스크립트가 더 잘 작동한다는 것을 알았습니다.

file -i "$@" |

에게

file --mime-type "$@" | 

(권한 수준이 있었다면 원래 답변에 주석으로 제공했을 것입니다)

답변1

globstar내 생각에 bash 옵션은 기본적으로 활성화되어 있지 않기 때문에 활성화하기만 하면 됩니다.우분투, 다음에 설명된 대로입니다.

표현식 /path/to/music/directory/{**/,}*에는 두 가지 확장 구조가 포함되어 있습니다. 중괄호 확장이 있고 그 다음에는 경로 이름 확장이 있습니다.

버팀대 확장

중괄호 확장은 다음 예를 통해 가장 잘 설명됩니다.

$ printf '%s\n' before-{a,bb,1,22}-after
before-a-after
before-bb-after
before-1-after
before-22-after

(저는 여기와 다음에서 각 요소를 새 줄에 인쇄하는 명령 printf '%s\n' item1 item2 etc..을 사용했습니다)echo

중괄호 안의 쉼표로 구분된 각 요소는 확장된 요소가 되는 것을 볼 수 있습니다.

중괄호 안에 요소 **/와 빈 요소가 포함된 원래 예는 다음과 같이 확장됩니다.

$ printf '%s\n' /path/to/music/directory/{**/,}*
/path/to/music/directory/**/*
/path/to/music/directory/*

글로브스타

**이제 두 번 언급된 bash glob으로 전환합니다.배쉬 매뉴얼 페이지, 둘 다 쉘 옵션과 관련되며 globstar의미는 다음과 같습니다.

경로 이름 확장 컨텍스트에 사용된 패턴 **은 파일과 0개 이상의 디렉터리 및 하위 디렉터리와 일치합니다.

이 쉘 옵션은활동적인우분투에서는 기본적으로:

$ shopt globstar
globstar        off

다음으로 활성화할 수 있습니다.

shopt -s globstar

( shopt -u globstar비활성화하는 데 사용).

다음과 같은 디렉토리 구조가 있는 경우:

$ find first/ | sort
first/
first/aaa
first/second
first/second/bbb01
first/second/bbb02
first/second/third
first/second/third/ccc1
first/second/third/ccc2
first/second/third/ccc3

다음과 같은 확장이 있을 수 있습니다.

$ printf '%s\n' first/**/a*
first/aaa

$ printf '%s\n' first/**/b*
first/second/bbb01
first/second/bbb02

$ printf '%s\n' first/**/c*
first/second/third/ccc1
first/second/third/ccc2
first/second/third/ccc3

**따라서 경로 이름 요소 이상으로 확장할 수 있음 을 알 수 있습니다 .

답변2

나는 이런 짓을 할 것입니다

#! /bin/bash

[[ -d "$1" ]] || { echo "$1 not a directory, exiting..."; exit 1; }

find "$1" -type f | while read F; do
  # do what you want with the "$F"
done

exit 0

그런 다음 다음을 통해 스크립트를 호출합니다../my_script <directory>

관련 정보