파일 이름의 숫자를 텍스트 파일의 해당 문자열로 바꿔 여러 파일의 이름을 바꿉니다.

파일 이름의 숫자를 텍스트 파일의 해당 문자열로 바꿔 여러 파일의 이름을 바꿉니다.

이름을 바꾸고 싶은 파일이 많습니다. 각 파일 이름에는 숫자(xxx)가 포함됩니다: FIXED_PART_xxx_UNIQUE_PART.

또한 각 줄에 숫자와 문자열이 포함된 텍스트 파일이 있습니다.

001 string001
002 string002
...
112 string112

각 파일에 대한 항목이 있지만 반드시 각 항목에 대한 파일이 있는 것은 아닙니다. 해당 부분을 구문 분석 하고 파일의 문자열로 바꿔서 xxx각 파일의 이름을 바꾸고 싶습니다.

가장 좋은 접근 방식은 무엇입니까?

편집: 실제 파일 이름은 다음과 같습니다.

Berlin_Ost_034_some_variable_text.jpg

따라서 이 경우 고정된 부분에도 밑줄이 포함되어 있지만 모든 폴더에 대해 동일합니다. xxx 부분은 숫자로만 구성됩니다.

출력은 파일의

Berlin_Ost_Sommer_some_variable_text.jpg

200개의 파일에 대해 이야기하고 있습니다.

텍스트 파일에는 034 Sommer라는 한 줄이 포함되어 있습니다.

이것이 파일의 034 부분이 Sommer로 대체된 이유입니다.

파일에는 다양한 문자열이 포함되어 있지만 문자, 숫자 및 독일어 발음 구별 부호만 포함되어 있습니다. 첫 번째 부분은 항상 숫자입니다. 이것은 내가 사용하는 파일 중 하나의 일부입니다.

033 Winter
034 Sommer
035 Herbst
036 Frühling
037 Abends.kurz.vor.Sonnenaufgang

저는 리눅스를 사용하고 있어요

답변1

zsh문자열에 공백이나 탭이 없다고 가정합니다 .

autoload -Uz zmv
typeset -A mapping=($(<mapping.txt))
zmv -n '(*_)([0-9](#c3))(_*.jpg)' '$1${mapping[$2]-$2}$3'

만족스러우면 삭제 -n(테스트 실행)합니다.

여러 밑줄 사이에 일련의 3자리 숫자가 포함된 파일 이름의 경우 가장 오른쪽 숫자가 대체됩니다. 이를 사용하면 ${mapping[$2]-$2}지도에서 숫자 시퀀스를 찾을 수 없는 경우 변경되지 않은 상태로 유지됩니다.

모든 파일의 접두사가 동일한 경우 다음을 수행할 수도 있습니다.

zmv -n '(Berlin_Ost_)([0-9](#c3))(_*.jpg)' '$1${mapping[$2]-$2}$3'

문자열에 공백이나 공백(처음이나 끝 제외)이 포함될 수 있는 경우 다음과 같이 연관 배열을 작성할 수 있습니다.

typeset -A mapping
while read -r key value; do mapping[$key]=$value; done < mapping.txt

대신에.

파일 이름에서 3자리 숫자를 모두 바꾸려면 다음을 수행할 수 있습니다.

zmv -n '*.jpg' '${f//(#m)[0-9](#c3)/${mapping[$MATCH]-$MATCH}'

이 경우 양쪽에서 밑줄을 찾지 않습니다. 우리는 할 수있어:

zmv -n '*.jpg' '${f//(#b)_([0-9](#c3))_/${mapping[$match[1]]-$match[1]}'

그러나 이것이 001and를 대체하는 반면, 두 번째 002는 첫 번째 게임에 포함되어 이후 게임의 일부가 될 수 없으므로 foo_001_bar_002_baz.jpg표시되지 않습니다 .foo_001_002_bar.jpg_

답변2

문자열 목록의 각 항목을 반복하여 일치하는 파일의 이름을 바꿀 수 있습니다. 한 줄로 압축할 수도 있지만 주석을 추가할 수 있도록 여기에 남겨둡니다.

while IFS=' ' read -r key value                            # Extract the key and value
do
    for file in *_"$key"_*                                 # Loop across all matches
    do
        [ -f "$file" ] &&
            mv -- "$file" "${file/_${key}_/_${value}_}"    # Replace key with value
    done
done <keysandvalues                                        # Read the file of matches

대체 표현식은 키의 첫 번째 항목만 대체하며 양쪽이 밑줄로 구분되어야 합니다. 키나 값은 모두 포함될 수 없습니다 /.

대체 파일 반복의 부작용은 파일 이름에 두 개의 대체 문자열(예: Berlin_033_other_035_text.jpg)이 포함된 경우 두 대체 문자열이 일치할 때 대체된다는 것입니다(여기서 결과는 입니다 Berlin_Winter_other_Herbst_text.jpg). 문제가 있는 경우 이름을 바꾼 파일을 별도의 디렉터리로 이동하면 문제가 해결될 수 있습니다.

답변3

_some_variable_text숫자가 포함되지 않는다고 가정하는 솔루션은 다음과 같습니다.

$ for i in *.jpg; do
    s="$(grep "${i//[^0-9]/}" file.txt)"
    echo mv -- "$i" "${i//[0-9]*/}${s//* /}_${i//*[0-9]_/}"
    # to actually perform the command remove the echo
    # do a backup first
  done
mv -- Berlin_Ost_034_some_variable_text.jpg Berlin_Ost_Sommer_some_variable_text.jpg

  • 파일을 반복합니다.
  • s="$(grep "${i//[^0-9]/}" file.txt)"키 추출;
  • mv -- "$i" "${i//[0-9]*/}${s//* /}_${i//*[0-9]_/}"파일 이름의 다른 부분을 얻으려면 매개변수 대체를 사용하여 파일 이름을 바꿉니다.

답변4

한 줄

prefix="foo" ls | grep -oP "(?<=${prefix}_).*" | xargs -I % sh -c 'mv ${prefix}_% ${prefix}_$( echo % | cut -d"_" -f1 | grep -f - filenames.txt | cut -d" " -f2 )_$( echo % | cut -d"_" -f2- ) '

foo접두사(FIXED_PART)와 파일 이름은 filenames.txt어디에 있습니까 ?

설명하다:

현재 디렉터리에서 로 시작하는 모든 파일 이름을 가져오지만 prefix접두사 뒤의 부분만 일치합니다 grep -oP "(?<=${prefix}_).*". 각 줄(1)에 대해 파일 이름을 + 에서 ++ 로 prefix바꿉니다 .(1)prefix(search in the file for the first part of (1), and get the corresponding string)remaining part of (1)

구경하다

관련 정보