저는 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 합계를 계산하여 출력합니다. 이를 사용하여 기능을 확인하고 이름 바꾸기를 시작하려면 두 번째 이름 echo
을 mv
.
설명하다
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/.*\.//')
다른 폴더에서 파일 이름을 반복적으로 바꿔야 하는 경우 find
with -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
스크립트는 md5sum
GNU coreutils의 유틸리티를 사용하여 주어진 경로 이름의 기본 이름(확장자 없음)을 기반으로 MD5 해시를 계산합니다. 도우미 함수는 md5name
실제 계산을 수행하고 전체 경로 및 확장명과 함께 새 이름을 출력합니다.
이 함수는 주어진 경로 이름의 부분 합계 결과를 기반으로 새 이름을 조합하는 데 md5name
사용됩니다 .awk
md5sum
기능 자체의 사용 예:
$ md5name '/some/path/file name here.extension'
/some/path/c9e89fa443d16da4b96ea858881320c9.extension
... c9e89fa443d16da4b96ea858881320c9
문자열의 MD5 해시는 어디에 있습니까 file name here
?
echo
실제로 파일 이름을 바꾸려면 상단의 스크립트에서 제거하세요. echo
어떤 시점에서 파일 이름을 원래 이름으로 복원해야 하는 경우 원본 스크립트의 출력을 파일(현재 위치)에 저장할 수 있습니다.
이것을 실행하는 것을 참고하세요두 배MD5 해시의 MD5 해시는 파일 세트에서 계산되며, 스크립트를 실행할 때마다 이름이 지정된 파일을 주의 깊게 기록하지 않으면 원본 파일 이름을 복구할 수 없게 됩니다.
답변3
와 함께 :perl
rename
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개의 매개변수를 가져와 할당 md5sum
및 sum
변수에 사용합니다. 공백이 없어야 하므로 file
제대로 작동합니다.sum
read
분명히 [echo]
이것은 실제로 실행될 때 제거되어야 하지만 검색을 테스트하기 위해 실행하기 전에 항상 스크립트 변경 사항을 테스트하는 것이 좋습니다.
이것은 모두 당신이 실행하고 있다고 가정합니다 bash
. 또는 하나의 긴 줄로 입력할 수도 있습니다.
find -iname \*.jpg -exec md5sum '{}' ';' | while read sum file ; do mv "$file" "`dirname $file`/$sum".jpg ; done