디렉터리의 모든 파일 이름을 해당 파일 이름의 md5 해시(콘텐츠 아님)로 바꿉니다.

디렉터리의 모든 파일 이름을 해당 파일 이름의 md5 해시(콘텐츠 아님)로 바꿉니다.

저는 Linux/명령줄을 처음 접했고 10,000개가 넘는 파일의 이름(고유 이름)을 암호화하여 mySQL 데이터베이스의 MD5 암호화된 이름과 일치해야 합니다.
파일 디렉터리의 이름을 바꾸는 방법과 파일의 해시를 얻는 방법을 알아냈습니다(mdsum?) 하지만 파일 이름의 해시를 가져온 다음 해당 파일의 이름을 생성된 해시로 바꾸고 확장자를 유지하는 방법이 막혔습니다.

mynicepicture.jpg > fba8255e8e9ce687522455f3e1561e53.jpg 

간단한 이름 바꾸기 또는 줄이어야 할 것 같지만 mv알아낼 수 없습니다.
귀하의 통찰력에 진심으로 감사드립니다.

추신: 제가 찾고 있는 것과 유사한 몇 가지 예에서 Perl 함수가 사용된 것을 보았지만 이를 어디서/어떻게 사용해야 하는지는 모릅니다.

답변1

어떤 쉘을 사용하고 싶은지 말하지 않았으므로 그냥 가정하고 있습니다.불다- 다른 쉘과 함께 작동하려면 답변을 조정해야 합니다.

for i in *; do sum=$(echo -n "$i"|md5sum); echo -- "$i" "${sum%% *}.${i##*.}"; done

스크립트 버전:

for i in *; do
  sum=$(echo -n "$i" | md5sum)
  echo -- "$i" "${sum%% *}.${i##*.}"
done

이 간단한 for루프는 현재 디렉터리의 각 파일을 가져와 해당 파일 이름의 md5 합계를 계산하여 출력합니다. 이를 사용하여 기능을 확인하고 이름 바꾸기를 시작하려면 두 번째 이름 echomv.

설명하다

  • echo -n "$i" | md5sum– md5 합계를 계산합니다.전체 파일 이름파일 확장자 포함(관로), 확장자를 echo -n "$i"다음 중 하나로 변경합니다.

    ${i%%.*}
    sed 's/\..*//' <<< "$i"
    echo "$i" | sed 's/\..*//'
    
  • sum=$(…)출력을 실행하고 $sum(명령 대체)

  • ${sum%% *}– 첫 번째 공백(매개변수 대체) 이는 다음 중 하나와 동일합니다.

    $(sed 's/ .*//' <<< "$sum")
    $(echo "$sum" | sed 's/ .*//')
    
  • ${i##*.}– 다음 중 하나와 동일하게 마지막 지점(인수 대체) 이후의 모든 항목을 출력합니다.

    $(sed 's/.*\.//' <<< "$i")
    $(echo "$i" | sed 's/.*\.//')
    

다른 폴더에서 파일 이름을 반복적으로 바꿔야 하는 경우 findwith -exec옵션을 사용하세요.

답변2

#!/bin/bash

md5name () {
    local base=${1##*/}
    local ext=${base##*.}
    local dir=${1%/*}

    printf '%s' "${base%.$ext}" | md5sum |
    awk -v dir="$dir" -v ext="$ext" '{ printf("%s/%s.%s\n", dir, $1, ext) }'
}

dir=$HOME  # where your files are

for pathname in "$dir"/*; do
    test -f "$pathname" || continue
    echo mv "$pathname" "$( md5name "$pathname" )"
done

bash스크립트는 md5sumGNU coreutils의 유틸리티를 사용하여 주어진 경로 이름의 기본 이름(확장자 없음)을 기반으로 MD5 해시를 계산합니다. 도우미 함수는 md5name실제 계산을 수행하고 전체 경로 및 확장명과 함께 새 이름을 출력합니다.

이 함수는 주어진 경로 이름의 부분 합계 결과를 기반으로 새 이름을 조합하는 데 md5name사용됩니다 .awkmd5sum

기능 자체의 사용 예:

$ md5name '/some/path/file name here.extension'
/some/path/c9e89fa443d16da4b96ea858881320c9.extension

... c9e89fa443d16da4b96ea858881320c9문자열의 MD5 해시는 어디에 있습니까 file name here?

echo실제로 파일 이름을 바꾸려면 상단의 스크립트에서 제거하세요. echo어떤 시점에서 파일 이름을 원래 이름으로 복원해야 하는 경우 원본 스크립트의 출력을 파일(현재 위치)에 저장할 수 있습니다.

이것을 실행하는 것을 참고하세요두 배MD5 해시의 MD5 해시는 파일 세트에서 계산되며, 스크립트를 실행할 때마다 이름이 지정된 파일을 주의 깊게 기록하지 않으면 원본 파일 이름을 복구할 수 없게 됩니다.

답변3

와 함께 :perlrename

find . -name '*.jpg' -type f -exec rename -n '
  BEGIN{use Digest::MD5 qw(md5_hex)}
  my ($dir, $name, $ext) = m{(.*)/(.*)\.(.*)}s;
  $_ = "$dir/" . md5_hex($name) . ".$ext"' {} +

(행복하면 삭제 -n).

답변4

한 가지 AWK방법의 경우:

find [Directory] -type f [various other find options] | 
     awk '{orig=$0; 
           match($0,/^.*\//,path); sub("^"path[0], "");
           match($0, /.[[^.]+$/,ext); sub(ext[0]"$", "");
           ("echo \"" $0 "\"|md5sum") | getline;
           com=sprintf("mv \"%s\" \"%s%s%s\"", orig, p[0], $1, ext[0]);
           print(com)
           }'

find최신 명령에는 입력 디렉터리가 필요하지 않다고 가정하므로 .[디렉터리]를 비워 둘 수 있습니다. 디렉토리를 좋아하지 않고 런타임에 디렉토리 이름을 변경하는 것은 좋은 생각이 아니기 -type f때문에 편리한 조회 파일 만 있습니다 . 특정 파일만 사용하려면 를 사용하고, 대소 문자가 중요한 경우 대신 을 사용하세요 .md5sum-iname pattern-iname \*.dat-name-iname

이러한 match(...); sub(...)조각은 파일 이름의 일부를 추출하여 입력 문자열에서 바꿉니다. [pre/app] "^"및 추가는 "$"경로/확장자를 중복할 수 있는 문자열의 교체를 방지하기 위한 것입니다.

실제로 이름 바꾸기를 수행하는 것으로 바꾸십시오. 예를 들면 다음과 print(com)같습니다 .system(com)

find -type f | 
     awk '{orig=$0; 
           match($0,/^.*\//,path); sub("^"path[0], "");
           match($0, /.[[^.]+$/,ext); sub(ext[0]"$", "");
           ("echo \"" $0 "\"|md5sum") | getline;
           com=sprintf("mv \"%s\" \"%s%s%s\"", orig, p[0], $1, ext[0]);
           system(com)
           }'

md5sum실제 파일 이름을 이름으로 사용하고 싶은 경우md5sum출력 합계와 입력 파일 이름이 다음과 같다는 사실을 활용할 수 있습니다.

 find -type f -exec md5sum '{}' ';' | 
     while read sum file ; do 
       [echo] mv "$file" "`dirname $file`/$sum".extension ; 
     done

while read sum file명령의 결과인 2개의 매개변수를 가져와 할당 md5sumsum변수에 사용합니다. 공백이 없어야 하므로 file제대로 작동합니다.sumread

분명히 [echo]이것은 실제로 실행될 때 제거되어야 하지만 검색을 테스트하기 위해 실행하기 전에 항상 스크립트 변경 사항을 테스트하는 것이 좋습니다.

이것은 모두 당신이 실행하고 있다고 가정합니다 bash. 또는 하나의 긴 줄로 입력할 수도 있습니다.

find -iname \*.jpg -exec md5sum '{}' ';' | while read sum file ; do mv "$file" "`dirname $file`/$sum".jpg ; done

관련 정보