find + sed + cp를 사용하여 파일을 찾아 다른 이름의 디렉터리에 복사합니다.

find + sed + cp를 사용하여 파일을 찾아 다른 이름의 디렉터리에 복사합니다.

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. 파일 이름에 공백이나 전역 문자가 있으면 ?*\[중단됩니다 . 를 사용하는 경우 findaction 을 통해 명령을 호출하도록 만드세요 -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

관련 정보