다음과 같은 구조의 디렉토리가 있습니다.
example
├───1
│ └───01-01-2015.txt
├───2
│ └───02-02-2016.txt
├───3
│ └───03-03-2017.txt
└───script.sh
모든 .txt 파일을 찾아 해당 파일 외부에 특정 폴더의 .txt 파일 이름을 기반으로 한 이름으로 새 폴더를 만드는 스크립트를 작성하려고 합니다.
결과는 다음과 같습니다.
example
├───1
│ ├───01-01-2015
│ └───01-01-2015.txt
├───2
│ ├───02-02-2016
│ └───02-02-2016.txt
├───3
│ ├───03-03-2017
│ └───03-03-2017.txt
└───script.sh
따라서 폴더 "3" 하위 폴더 "03-03-2017", 폴더 "2" 하위 폴더 "02-02-2016" 등입니다.
모든 .txt 파일을 찾는 것이 매우 간단하다는 것을 알고 있지만 이를 디렉토리 생성 및 각 검색 결과에 대한 하위 문자열 수행과 결합하는 방법을 알 수 없습니다.
미리 감사드립니다! !
답변1
find example -name \*.txt | sed 's/\.txt$//' | xargs -n 1 mkdir
경고: 경로가 필요합니다아니요개행 문자를 포함합니다.
편집: GNU 도구를 사용하는 경우 terdon의 설명을 참조하세요.
답변2
이를 위해 bash 루프를 사용합니다.
for i in **/*.txt; do mkdir "${i%.txt}"; done
귀하의 예에서 이것을 실행하면 다음과 같은 결과를 얻습니다.
$ tree
.
├── 1
│ └── 01-01-2015.txt
├── 2
│ └── 02-02-2016.txt
└── 3
└── 03-03-2017.txt
3 directories, 3 files
$ shopt -s globstar
$ for i in **/*.txt; do mkdir "${i%.txt}"; done
terdon@oregano foo $ tree
.
├── 1
│ ├── 01-01-2015
│ └── 01-01-2015.txt
├── 2
│ ├── 02-02-2016
│ └── 02-02-2016.txt
└── 3
├── 03-03-2017
└── 03-03-2017.txt
6 directories, 3 files
globstar
bash 옵션이며 다음과 같이 설명됩니다 man bash
.
글로벌 스타
**
설정된 경우 경로 이름 확장 컨텍스트에 사용된 패턴은 모든 파일과 0개 이상의 디렉터리 및 하위 디렉터리와 일치합니다. 패턴 뒤에 가 오면/
디렉터리와 하위 디렉터리만 일치합니다.
따라서 를 사용하여 활성화한 후 shopt -s globstar
이 모드는 **/*.txt
이름이 로 끝나는 모든 파일(또는 디렉터리)을 찾습니다 .txt
.
쉘 구문은 ${i%.txt}
하위 문자열을 제거하는 데 사용됩니다. 일반적인 형식은 변수 끝에서 첫 번째 인스턴스를 제거 ${variable%string}
하는 것 입니다. string
따라서 ${i%.txt}"
파일 이름(상위 디렉터리 포함)에서 를 뺀 값이 됩니다 .txt
. 따라서 이를 [에 전달하면 mkdir
원하는 디렉터리가 생성됩니다.
개인적으로 위 구문이 더 간단하다고 생각하지만 사용 방법은 다음과 같습니다 find
.
find . -name '*.txt' -exec sh -c 'mkdir ${0%.txt}' {} \;
여기에서 각 결과를 -exec command {}
교체 한 다음 실행해 보세요. 여기의 명령은 에 대한 호출이므로 0번째 위치 인수로 사용 됩니다 . 따라서 위에서 설명한 것과 동일한 쉘 대체를 실행하여 디렉토리를 만듭니다.{}
find
command
sh -c
sh
{}
$0