Folder.jpg라는 파일을 한 폴더에 복사하려고 합니다. 문제는 모든 파일의 이름이 동일하기 때문에 프로세스 중에 이름을 바꿔야 한다는 것입니다. sed를 사용하여 이 작업을 수행할 수 있다는 것을 알고 있지만 이름을 상위 폴더의 일부인 이름으로 바꾸고 싶습니다. 파일을 찾아 복사해서 얻은 결과입니다.
cp $(find . -iname "folder.jpg") .albumart/
폴더 구조는 ./artist/artist.year.album/folder.jpg이고 상위 폴더(또는 그 일부)를 사용하여 파일 이름을 지정하고 싶습니다. 라이너 작업을 완료하는 데 도움을 줄 수 있는 사람이 있나요? 문제를 더 복잡하게 만들기 위해 일부 폴더에는 존재하는 경우 무시하고 싶은 CD1 및 CD2 레이어도 있습니다(예: ./artist/artist.year.album/CD1/folder.jpg).
답변1
bash
이 버전은 폴더 구조(예: )를 사용 하고 ./foo/bar/baz/folder.jpg
모든 슬래시를 밑줄로 바꿉니다(예: 다음과 같습니다 foo_bar_baz_folder.jpg
).
find . -iname folder.jpg -exec bash -c 'for x; do x=${x#./}; cp -i "$x" ".albumart/${x//\//_}"; done' _ {} +
무엇을 하든 여러 위치에서 동일한 대상으로 파일을 이동할 때마다 이름이 충돌할 가능성이 항상 있다는 점에 유의하세요.
답변2
zsh 사용:
autoload zmv
zmv -n -C '(**/)folder.jpg' '.albumart/${1:t}.jpg'
만족스러우면 삭제하세요 -n
.
이렇게 하면 이름 충돌이 방지됩니다(두 개의 대체 항목이 동일한 이름으로 확인되면 오류와 함께 실패함). 예:
$ zmv -n -C '(**/)folder.jpg' '.albumart/${1:t}.jpg'
zmv: error(s) in substitution:
b/c/folder.jpg and a/b/c/folder.jpg both map to .albumart/c.jpg
답변3
출력을 구문 분석하지 마십시오 find
. 파일 이름에 공백이나 전역 문자가 있으면 ?*\[
중단됩니다 . 를 사용하는 경우 find
action 을 통해 명령을 호출하도록 만드세요 -exec
. -exec
필요한 문자열 변환을 수행하기 위해 작업 중에 셸이 호출됩니다 .
find -name folder.jpg -exec sh -c '
dir=${0%/*} # stip off the file name
case $dir in */CD[0-9]) dir=${dir%/*};; esac
cp -ip "$0" ".albumart/${dir##*/}.jpg"
' {} \;
지쉬의즈마브일반적으로 이러한 복사본을 만드는 가장 쉬운 방법은 다음과 같습니다.
zmv -C -o-p -w '**/*.jpg' '.albumart/${${${1%/}/CD<->}##*/}.jpg'
몇 가지 설명:
- 일반적인 구문은 입니다
zmv OPTIONS… SOURCE_PATTERN REPLACEMENT
. -w
와일드카드 그룹 일치를 활성화합니다. 대체 텍스트에서는$1
일치하는 부분**/
(/
일치하는 텍스트가 비어 있지 않은 경우, 즉 파일이 최상위 디렉터리에 있는 경우) 을 참조하고$2
일치하는 부분을 참조합니다.*
*.jpg
- 패턴과 대체 텍스트 모두 확장으로부터 보호되어야 합니다. 문자 그대로 에 전달되어야 합니다
zmv
. - 이해하려면
${${${1%/}/CD<->}##*/}
내부부터 시작해야 합니다. 먼저 을 가져오고$1
마지막 항목을 제거합니다/
(있는 경우). 최종 패턴 일치 제거/CD<->
(있는 경우)<->
하나 이상의 숫자와 일치). 마지막으로 마지막 디렉터리 구성 요소를 제외한 모든 항목을 닫습니다. - 공백을 밑줄로 바꾸려면 다른 레이어를 추가하세요매개변수 확장:
${${${${1%/}/CD<->}##*/}// /_}
.
답변4
분명히 이 답변은 늦었지만 다른 사람들도 유용하다고 생각할 수 있기를 바랍니다.
for i in $(find . -type f -iname "folder.jpg" -printf "%P\n") ; do t=$(echo $i | sed 's|/|\.|g'); cp $i TARGETDIR/$t ; done
의 목적은 의 출력에서 선행을 제거하는 것입니다 -printf "%P\n"
../
find
find
결과( $i
)를 에코 sed
하고 변경합니다. 이 경우 sed는 /
으로 대체되고 .
전체 결과의 값을 다음에 할당합니다.t
그런 다음 찾은 파일( find
이 $i
경우)을 새 이름으로 TARGETDIR에 복사하세요 $t
.
발견: ./artist/artist.year.album/folder.jpg
수율: TARGETDIR/artist.artist.year.album.folder.jpg