경로 이름으로 파일 이름 바꾸기

경로 이름으로 파일 이름 바꾸기

하위 폴더 안에 .bdf 파일이 있습니다. 모든 .bdf의 이름은 Loads.bdf와 같습니다.

예:

/home/user/folderxx/folderxxx/Load.bdf
/home/user/folderxx/folderxxx/Load.bdf

모든 Load.bdf 파일을 찾아서 새 폴더에 복사하고 경로 이름으로 이름을 바꿔야 합니다.

예: 의도한 작업 후에는 다음과 같이 표시되어야 합니다.

folder001_folderAAA_Load.bdf
folder002_folderBBB_Load.bdf

답변1

이를 위해 ("다중 이동") 패키지 mcp의 도구를 사용합니다 .mmv

mcp '/home/user/*/*/Load.bdf' '#1_#2_Load.bdf'

두 번째 문자열의 등 #1#2첫 번째 문자열의 해당 첫 번째, 두 번째 등 와일드카드 내용으로 대체됩니다. 와일드카드가 mcp셸이 아닌 에 의해 해석되도록 경로는 작은따옴표로 묶여 있습니다 .

표시된 명령을 사용하면 파일이 현재 디렉터리에 복사됩니다. mcp로 바꾸면 mmv파일이 대신 이동됩니다.

답변2

prename(많은 시스템에서 별칭으로 사용)을 사용하면 또는 rename를 여러 번 실행하지 않고도 이 작업을 수행할 수 있습니다 .mvcp

cd /home/user
find . -type f -name 'Loads.bdf' -exec \
  prename -n 's:^./::; s:/:_:g; s:^:destination/:' {} +

-n원하는 파일이 이동되고 있다고 확신하면 제거하십시오 .

업데이트

파일을 이동하는 대신 복사하려면 가장 빠른 방법은 cpio또는 를 사용하여 먼저 복사한 pax다음 이전과 같이 이름을 바꾸는 것입니다. 예(GNU 사용 cpio):

cd /home/user
find . -type f -name 'Loads.bdf | cpio -p --make-directories destination

cd destination
find . -type f -name 'Loads.bdf' -exec  prename -n 's:^./::; s:/:_:g' {} +

paxPOSIX이자 LSB이며 더 cpio이상 POSIX가 아니지만 cpio여전히 많은 시스템에서 일반적으로 발견되는 프로그램입니다.

findGNU / 를 사용하여 개행 문자가 있는 파일 이름을 처리하려면 to 및 to에 cpio추가하는 것이 가능합니다 .-print0find-0cpio

업데이트 2

해결책 pax은 한 줄로 구성됩니다( 제외 cd).

cd /home/user
find . -name 'Loads.bdf' | cut -d/ -f 2- | pax -rws ':/:_:g' destination

또는 파일 이름(및 GNU )의 경우 find:

find /home/user -name 'Loads.bdf' -printf '%P\0' | pax -0rws ':/:_:g' destination

답변3

다른 답변(예: mcp 및 mmv 또는 prename)에 언급된 도구가 없는 시스템에서 이 작업을 수행해야 하고 쉘에서 완전히 수행하려는 경우 다음 작업을 수행할 수 있습니다. 좋다:

#!/usr/bin/env bash

oldpath="/home/user"
newpath="/home/user/newfolder"

for file in $(find $oldpath -type f -name Load.bdf); do
        shortname=${file#$oldpath/}
        newname="$newpath/${shortname//\//_}"
        if [ -f $newname ]; then
                echo "$newname already exists."
        else
                echo "copy: $file"
                echo "  --> $newname"
                cp $file $newname
        fi
done

Load.bdf이 스크립트는 디렉터리 에 있는 모든 파일을 찾아 oldpath디렉터리 이름을 새 파일 이름으로 변환한 다음 대상 디렉터리에 복사합니다. 또한 두 번 이상 실행해야 하고 모든 파일을 다시 복사할 필요가 없는 경우를 대비하여 이미 복사된 파일이 있는지 확인할 수도 있습니다.

결과 디렉토리 구조는 다음과 같습니다.

bash$ find . -type f
/home/user/folder001/folderAAA/Load.bdf
/home/user/folder002/folderBBB/Load.bdf
/home/user/folder003/folderCCC/Load.bdf
/home/user/newfolder/folder001_folderAAA_Load.bdf
/home/user/newfolder/folder002_folderBBB_Load.bdf
/home/user/newfolder/folder003_folderCCC_Load.bdf

답변4

env - sh <<\SCRIPT

    t=/home/user/target f=folder
    cd "${t%/*}" && mkdir -p "$t"
    set -- $f??/$f???/Load.BDF
    while [ -e "$1" ] ; do
        cp "$1" "$t/$(IFS=/
            printf '%s_%s_%s\n' $1)"
    shift ; done

SCRIPT

나는 이것이 모두 완전히 이식 가능한 쉘 스크립트라고 생각합니다. 처음에는 의심이 있었지만 꽤 간단하게 완료되었습니다.

관련 정보