파일 이름을 바꾸려면 FIND 및 MV를 사용하십시오. 찾은 문자열을 제거한 다음 파일 이름에 추가하시겠습니까?

파일 이름을 바꾸려면 FIND 및 MV를 사용하십시오. 찾은 문자열을 제거한 다음 파일 이름에 추가하시겠습니까?
find . -type f -name '*authors-name-string*' -exec bash -c 'mv "$0" "${0/authors-name-string/}"' {} \;

파일 이름에 무작위로 포함된 작성자 이름의 텍스트 문자열이 포함된 여러 수준의 디렉터리에 중첩된 파일의 이름을 바꾸려고 합니다. 작성자 이름으로 시작하고 나머지 원본 파일 이름이 뒤에 오는 새 파일 이름을 만듭니다. 그러나 원본 파일 이름의 임의 위치에 작성자 이름 문자열은 없습니다.

위의 셸 명령줄은 파일 이름에서 Authors-name-text 문자열을 재귀적으로 제거하지만 아직 어떻게 해야 할지 찾지 못했습니다. 그리고 Authors-name-text(및 후행 "_" 밑줄)를 The에 추가합니다. 파일 이름의 시작 부분. 기본적으로 작성자 이름 텍스트를 파일 이름의 현재 위치에서 파일 이름의 시작 부분(밑줄 포함)으로 이동하고 싶습니다. 내가 아는 한, 내 Synology NAS에서 호출되는 bash 버전은 v4.3입니다. MacBook에서 SSH를 통해 로그인했습니다.

간단한 디렉토리 목록을 볼 때 동일한 작성자가 작성한 디렉토리의 일부 파일이 함께 그룹화되어 표시되도록 주제 디렉토리 이름으로 구성된 다양한 디렉토리에 있는 수천 개의 파일을 가져오려고 합니다.

find . -type f -name '*authors-name-string*' -exec bash -c 'mv "$0" "authors-name-string_${0/authors-name-string/}"' {} \;

전체 파일 이름 경로 앞에 "authors-name-string_"을 삽입하려고 하면 위 명령줄이 실패합니다. 그러나 해당 이름에 대한 시작 디렉토리가 없기 때문에 MV 명령은 불평하지만 필요한 경우 파일 이름의 원래 위치에서 작성자 이름 문자열을 제거합니다.

답변1

분석법을 확장하고 매개변수 확장을 활용하세요.

export author_string='author1'
export new_string='author1'
find . -type f -name "*${author_string}*" \
  -exec sh -c '
    path="${1%/*}"
    tmp="${1%%${author_string}[^/]*}"
    before="${tmp##*/}"
    after="${1##*${author_string}}"
    echo mv -- "$1" "${path}/${new_string}_${before}${after}"' sh {} \;

귀하의 질문을 완전히 이해하지 못했기 때문에 내 가정은 다음과 같습니다.

이름에 고정 문자열이 포함된 파일을 검색하고 있습니다 author_string. 여기서는
디렉토리 트리의 모든 위치에서 파일 이름을 바꾸고 있습니다.
파일의 새 이름은 고정된 문자열로 시작됩니다(동일 author_string하거나 다른 경우에는 큰 차이가 없습니다). 여기서는 변수입니다 new_string. 파일의 새 이름 중 나머지 부분은
이전 이름과 동일합니다. author_string제거됩니다.

이 코드에서는:

  • 호출 쉘에서 사용할 수 있도록 이전/새 문자열을 내보냅니다 find.

  • 이식성을 염두에 두고 코드 조각에 표시된 대로 -execinvocation 을 대신 사용하세요 sh. 일반적으로 셸/명령의 이름을 설정하는 데 사용되기 때문입니다.$1$0$0

  • 각 파일에 대해 전체 경로를 분할합니다.

    • path="${1%/*}"파일 이름 부분이 제거된 전체 경로입니다. ${parameter%word}패턴과 일치하는 접미사를 제거합니다 word.

    • tmp="${1%%${author_string}[^/]*}"각 파일의 전체 경로 중 앞 부분을 캡처합니다 author_string. ${parameter%%word}제거가장 긴패턴과 일치하는 접미사입니다 word. 우리는 일반적으로 [^/]디렉터리 이름에 이런 내용이 있으면 무시합니다.author_string

    • before="${tmp##*/}"파일 이름의 하위 문자열만 캡처: ${parameter##word}패턴과 일치하는 가장 긴 접두사를 제거합니다 word.

    • after="${1##*${author_string}}"파일명 다음 부분입니다 author_string.

  • 각 파일의 이름을 바꿉니다.

파일 이름에서 반복 되면 author_string두 발생 사이의 모든 내용이 손실됩니다.

또한 문자 그대로 일치시키려면 \특별한 패턴 일치 의미가 있는 문자를 이스케이프(사용) 해야 한다는 점을 명심하세요.author_string

디렉토리 트리가 주어지면:

$ tree .
.
├── testdir
│   ├── title2_author1_date.book
│   ├── title3_author1_date.book
│   └── title4_author2_date.book
├── title1_author1_date.book
└── title5_author2_date.book

이 코드의 기능은 다음과 같습니다.

$ export author_string='author1' new_string='author1'; find . -type f -name "*${author_string}*" -exec sh -c 'path="${1%/*}"; tmp="${1%%${author_string}[^/]*}"; before="${tmp##*/}"; after="${1##*${author_string}}"; echo mv -- "$1" "${path}/${new_string}_${before}${after}"' sh {} \;
mv -- ./title1_author1_date.book ./author1_title1__date.book
mv -- ./testdir/title3_author1_date.book ./testdir/author1_title3__date.book
mv -- ./testdir/title2_author1_date.book ./testdir/author1_title2__date.book

echo실제로 파일 이름을 바꿀 준비가 되었다고 생각되면 명령에서 해당 파일을 제거하십시오.


인용하다:

매개변수 확장"The Open Group Base Spec Issue 7, 2018 Edition"(POSIX.1-2017)에서

답변2

Larry Wall의 직업인 것 같네요 rename. 같은 이름을 가진 다른 명령이 있다는 점에 유의하십시오. 이 명령은 안뜨기하다로 작성되었습니다.

관련 정보