상위 디렉토리를 기반으로 파일 이름을 바꾸려면 find/xargs 명령을 사용하시겠습니까?

상위 디렉토리를 기반으로 파일 이름을 바꾸려면 find/xargs 명령을 사용하시겠습니까?

다음과 같은 디렉토리 구조가 있습니다.

Project/
  |
  +--Part1/
  |    |
  |    +--audio.mp3
  |
  +--Part2/
  |    |
  |    +--audio.mp3
  |
  +--Part3/
  |    |
  |    +--audio.mp3
...

Part1.mp3, Part2.mp3 등의 파일로 만들고 싶습니다.

각 폴더에는 파일이 하나만 포함되어 있으므로 파일이 손상되거나 동일한 이름을 가진 여러 파일을 처리할 위험이 없습니다.

find일종의 / xargs명령 플러스 및 을 사용하여 cut이 작업을 수행 할 수 있을 것 같지만 mv실제로 명령을 구성하는 방법을 모르겠습니다.

답변1

이러한 예제는 모든 POSIX 셸에서 실행될 수 있으며 외부 프로그램이 필요하지 않습니다.

이렇게 하면 Part*.mp3 파일이 프로젝트 디렉터리와 동일한 수준에 저장됩니다.

(cd Project && for i in Part*/audio.mp3; do echo mv "$i" ../"${i%/*}".mp3; done)

이렇게 하면 프로젝트 디렉터리에 Part*.mp3 파일이 남게 됩니다.

for i in Project/Part*/audio.mp3; do echo mv "$i" ./"${i%/*}".mp3; done

이러한 솔루션은 셸을 사용하여 pattern matching parameter expansion새 파일 이름을 생성합니다.

 ${parameter%word}     Remove Smallest Suffix Pattern.  The word is expanded
                       to produce a pattern.  The parameter expansion then
                       results in parameter, with the smallest portion of
                       the suffix matched by the pattern deleted.

답변2

renamePerl (때때로 호출됨 ) 이 있는 경우 prename다음을 수행할 수 있습니다.

( cd Project && rename 's!(.+)/(.+)(\.mp3)!$1.$3!' */audio.mp3 )

이는 쉘 글로브와 일치하는 모든 파일 이름을 가져와 */audio.mp3이를 디렉토리, 파일 이름 및 확장 구성 요소로 분할합니다. 그런 다음 파일 이름 부분을 버리고 파일 이름을 바꿉니다.

rename -n ...무슨 일이 일어나는지 확인하는 데 사용 하거나, 실행 시 어떤 일이 일어나는지 확인하는 데 -v대신 사용하세요.-n

답변3

pax -rwls'|.*/\(.*\)/audio\(\.mp3\)$|\1\2|p' \
    -s'|.*||' /path/to/Project .

이는 POSIX 명령줄 보관 유틸리티를 사용하여 트리에서 발견된 각 루트 디렉터리 pax에 대해 명명된 현재 디렉터리에 하드 링크를 생성합니다.parent_dirs_base.mp3audio.mp3/path/to/Project. 이렇게 하면 stderr에 대한 파일 이름 수정 사항이 모두 인쇄됩니다.

-k링크 대상과 동일한 이름을 가진 기존 파일을 잠재적으로 덮어쓰는 것을 방지하거나 더 나은 방법으로 실행하기 전에 먼저 빈 디렉터리로 변경하는 것을 방지하는 데 사용됩니다 .

mv제 생각에는 사용하려는 파일을 직접 연결하는 대신 먼저 하드 링크를 만드는 것이 상당한 이점이 있습니다. 즉, 기대하는 결과가 얻는 결과와 동일한지 확인할 수 있는 기회가 있다는 것입니다.앞으로원본을 삭제하세요. 확인한 후 다음을 수행할 수 있습니다.

find /path/to/Project -name audio.mp3 -exec rm {} +

...파일 링크를 정리하고 하나씩 줄이세요.

답변4

Perl 맛을 사용한 Bash

for file in `find . -type f -name "*.mp3"`;
    do
        dir=$(dirname $file);
        bdir=$(basename $dir);
        bname=$(basename $file);
        new=$bdir.$bname;
        newname=${new//\.\./};
        newname_with_path=$dir/$newname
        if [ "$file" != "$newname_with_path" ]
        then
            echo mv -u $file  $newname_with_path ;
        fi
    done


    # replace 2 dots with nothing
    # bash 4.1.2 centos 6.4 no problem with or without bashslash
    newname=${new//../};

관련 정보