이 명령을 사용하여 파일 이름을 바꿉니다.
for fname in *;
do
mv "$fname" $(echo "$fname" | sha1sum | cut -f1 -d' ')
done
그러나 현재 디렉토리에서만 이름이 변경됩니다. 많은 디렉터리가 있고 각 디렉터리에는 다른 디렉터리가 포함되어 있으며 마지막 디렉터리 트리에는 파일이 포함되어 있다고 가정해 보겠습니다. 임의의 문자로 이름을 바꾸고 싶습니다.
나는 그것이 작동해야 한다고 생각 find . -type f
하고 시도해 보았지만 여전히 작동 명령을 얻지 못했습니다.
답변1
그리고 다음을 찾으세요:
find . -type f -exec sh -c 'SHELL COMMAND' {} \;
이는 SHELL COMMAND
발견된 각 파일을 차례로 호출합니다. "$0"
따라서 파일 이름은 입니다.
find . -type f -exec sh -c '
mv "$0" "${0%/*}/$(printf "%s\n" "${0##*/}" | sha1sum | cut -d" " -f1)"
' {} \;
( 파일 이름이 있거나 문제를 일으킬 수 있는 다른 상황이 있는 경우 printf
대신 사용하십시오 .)echo
-e
-n
echo
셸을 일괄적으로 호출하면 작업 속도를 높일 수 있습니다.
find . -type f -exec sh -c 'for x; do
mv "$x" "${x%/*}/$(printf "%s\n" "${x##*/}" | sha1sum | cut -d" " -f1)";
done' _ {} +
zsh에는 현재 디렉터리와 하위 디렉터리의 모든 파일을 재귀적으로 일치시키는 간단한 방법이 있습니다. 이것.
글로벌 예선일반 파일로 일치를 제한하고 D
도트 파일을 포함합니다.
for x in **/*(.D); do mv …; done
Bash ≥ 4에서는 재귀적으로 실행 shopt -s globstar
하고 **/*
현재 디렉터리와 하위 디렉터리의 모든 파일을 일치시키는 데 사용할 수 있습니다. 루프에서 일반 파일을 필터링해야 합니다.
shopt -s globstar; GLOBIGNORE=".:.."
for x in **/*; do if [[ -f $x ]]; then mv …; done
답변2
도우미 스크립트 /tmp/tmp.sh를 만듭니다.
#!/bin/bash
mv "$1" $(echo "$1" | sha1sum | cut -f1 -d' ')
실행 가능하게 만든 다음 호출하십시오.
find . -type f -execdir /tmp/tmp.sh {} ";"
답변3
Bash 4+를 사용하는 경우 다음을 수행할 수 있습니다.
#!/bin/bash
shopt -s globstar
for fname in **/*; do
if [ -f "$fname" ]; then
mv ...
fi
done
Bash Hacker Wiki에서:
새로운 쉘 옵션 globstar가 있습니다. 활성화되면 Bash는 **에서 재귀적 와일드카드를 수행합니다. 즉, 현재 수준뿐만 아니라 파일 시스템의 현재 위치에 있는 모든 디렉터리 및 파일과 일치합니다.
답변4
이것은 모든 공백을 처리합니다 ...
set -f; IFS=
while read -r -d $'\0' fname ;do
mv ...
done < <(find . -type f -name '*' -print0)
set +f; IFS=$' \t\n' # you don't have to reset unless it effects subsequent code