이메일 파일 이름을 .txt에서 .eml로 반복적으로 바꿉니다.

이메일 파일 이름을 .txt에서 .eml로 반복적으로 바꿉니다.

"$d" 디렉터리에는 .txt 확장자를 가진 수천 개의 이메일 파일이 포함되어 있습니다. 이메일 클라이언트에서 열려면 이름을 .eml로 바꿔야 합니다.

이 명령은 이름을 올바르게 바꾸나요?

find "${d}" -type f -name '*.txt' | while read f; do mv -vn "${f}" "${f%.*}".eml; done

아니면 이를 수행하는 더 좋고 더 강력한 방법이 있습니까?

나는 우아한 사용 방법을 생각할 수 없습니다.

-exec ...{}... \;

답변1

귀하의 솔루션은 일반적으로 괜찮지 만 줄 바꿈으로 인해 중단됩니다. 다음은 약간 더 강력한 bash4+ 솔루션입니다.

shopt -s globstar nullglob
for file in **/*.txt; do
    mv "$file" "${file%.*}.eml"
done

답변2

내 생각에는 당신이 괜찮을 것 같아요

find "$d" -name \*.txt -exec rename .txt .eml {} \;

심지어

for f in *.txt; do rename .txt .eml "$f"; done

모든 파일이 동일한 디렉토리에 있는 경우.

답변3

bash예, 비슷한 구문의 셸을 사용한다고 가정하면 명령이 작동합니다. 앞으로 이와 같은 대규모 명령 사용을 고려할 때 echo명령줄을 사용하여 결과를 미리 볼 수 있다는 점을 기억하세요. 즉, 앞에 놓고 echo파이프 mv라인을 실행하여 명령이 무엇인지 확인할 수 있습니다. 괜찮아 보이면 삭제 echo하고 실제로 명령을 실행하세요.

답변4

zsh에서는zmv이것을 쉽게 만드십시오. autoload -U zmvyours 를 입력 ~/.zshrc한 후 여러 방법 중 하나를 사용하여 **/*.txt현재 디렉터리 및 하위 디렉터리의 확장자를 가진 파일과 일치하는 대체 텍스트를 지정합니다.txt

zmv '**/*.txt' '$f:r.eml'
zmv '**/*.txt' '${f%.*}.eml'
zmv '(**/)(*).txt' '$1$2.eml'
zmv -w '**/*.txt' '$1$2.eml'

zsh는 없지만 bash ≥4 또는 ksh93이 있는 경우 **재귀를 사용하여 하위 디렉터리를 순회한 다음 일치 항목을 반복할 수 있습니다. bash(당신의 것에 넣으세요 ) 또는 ksh(당신의 것에 넣으세요 )를 사용하여 **먼저 glob 모드를 활성화 해야 합니다 . 이는 zsh에서도 작동합니다(사전 설정이 필요하지 않음).shopt -s globstar~/.bashrcset -o globstar~/.kshrc

for f in **/*.txt; do mv -- "$f" "${f%.*}.eml"; done

이렇게 하면 일반 파일뿐만 아니라 모든 파일의 이름이 변경됩니다. 디렉토리나 기타 비정규 파일이 있고 이를 변경하지 않고 유지하려는 경우:

zmv -Q '**/*.txt(.)' '$f:r.eml'
for f in **/*.txt; do [[ -f $f ]] && mv -- "$f" "${f%.*}.eml"; done

POSIX 외부에는 셸 기능이 없으므로 find하위 디렉터리를 탐색하려면 호출해야 합니다. 백슬래시, 후행 공백 또는 줄 바꿈이 포함된 파일에서는 솔루션이 손상되기 때문에 취약합니다. 다음 명령을 사용하여 후행 공백 및 백슬래시 문제를 해결할 수 있습니다.while IFS= read -r f; do …그러나 파이프로 연결된 출력은 find본질적으로 개행에서 중단됩니다. 대신 사용하십시오 -exec. Linux에서는 이 유틸리티를 사용할 수 있습니다 rename(배포판과 함께 제공되는 것이 무엇이든). Debian, Ubuntu 및 그 파생물:

rename 's/\.txt$/.eml/' **/*.txt
find . -name '*.txt' -type f -exec rename 's/\.txt$/.eml/' {} +

.txt다른 배포판에서는 중간에 파일 이름이 없는 한 ( rename소스 문자열의 첫 번째 항목이 대체되므로):

rename .txt .eml **/*.txt
find . -name '*.txt' -type f -exec rename .txt .eml {} +

프로세스 전체에서 POSIX 기능만 사용되며 이름 변환을 수행하기 위해 셸을 호출합니다.

find . -name '*.txt' -type f -exec sh -c 'for f; do mv "$f" "${f%.*}.eml"; done' _ {} +

find를 지원하기에는 버전이 너무 오래된 경우 -exec … +각 파일에 대해 셸을 호출해야 합니다. 이렇게 하면 코드가 더 단순해지지만 속도가 느려집니다.

find . -name '*.txt' -type f -exec sh -c 'mv "$0" "${0%.*}.eml"; done' {} \;

관련 정보