파일 및 디렉터리의 이름을 반복적으로 바꿉니다.

파일 및 디렉터리의 이름을 반복적으로 바꿉니다.

이 명령을 사용하여 파일 이름을 바꿉니다.

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-necho

셸을 일괄적으로 호출하면 작업 속도를 높일 수 있습니다.

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는 **에서 재귀적 와일드카드를 수행합니다. 즉, 현재 수준뿐만 아니라 파일 시스템의 현재 위치에 있는 모든 디렉터리 및 파일과 일치합니다.

http://wiki.bash-hackers.org/bash4

답변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

관련 정보