쉘 스크립트를 사용하여 Linux에서 모든 파일 이름의 공백을 밑줄로 바꾸는 방법은 무엇입니까?


17

모든 XML 파일 이름의 공백을 바꿔야하는 쉘 스크립트를 시도했습니다.

for xml_file in $(find $1 -name "* .xml" -type f);
do
 echo "removing spaces from XML file:" $xml_file
 mv "$xml_file" "${xml_file// /_}";
done

이름이 xml 파일이 있고 xy z.xml다음을 제공 한다고 가정 해보 십시오.

removing spaces from XML file: /home/krishna/test/xy
mv: cannot stat `/home/krishna/test/xy': No such file or directory
removing spaces from XML file: .xml
mv: cannot stat `z.xml': No such file or directory

답변:


28

이것을 다음과 함께 사용하십시오 bash:

find $1 -name "* *.xml" -type f -print0 | \
  while read -d $'\0' f; do mv -v "$f" "${f// /_}"; done

find이름에 공백이있는 파일을 검색합니다. 파일 이름은 -print0특수 파일 이름을 처리하기 위해 구분 기호로 널 바이트 ( ) 와 함께 인쇄됩니다 . 그런 다음 read내장은 널 바이트로 구분 된 파일 이름을 읽고 마지막으로 mv공백을 밑줄로 바꿉니다.

편집 : 디렉토리에서 공백을 제거하려면 조금 더 복잡합니다. 디렉토리 이름이 바뀐 다음 이름으로 더 이상 액세스 할 수 없습니다 find. 이 시도:

find -name "* *" -print0 | sort -rz | \
  while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done

sort -rz폴더에서 가장 깊은 파일을 이동, 제 1 및 폴더 자체가 마지막이 될 것입니다 그래서, 파일 순서를 반전시킵니다. 따라서 모든 파일과 폴더의 이름이 변경되기 전에는 폴더 이름이 변경되지 않습니다. mv루프 의 명령도 약간 변경되었습니다. 대상 이름에서는 파일의 기본 이름에서 공백 만 제거합니다. 그렇지 않으면 액세스 할 수 없습니다.


모든 디렉토리에서 공백을 밑줄로 바꾸려고하지만 이름을 변경 한 후 디렉토리에 액세스 할 수 없으므로 오류가 발생합니다.
krishna

@ krishna 내 답변에 편집 내용을 추가했습니다.
혼돈

1
와우 @chaos, 두 시스템에서이 두 가지를 실행하고 그것은 매력, 몇 개의 파일과를 통과하지 DIRS처럼 일하지만 몇입니다
somethingSomething

macOS에서는 -name 옵션 앞에 find 명령에 디렉토리를 지정해야합니다. find . -name "* *" -print0 | sort -rz | \ while read -d $'\0' f; do mv -v "$f" "$(dirname "$f")/$(basename "${f// /_}")"; done
Laszlo Pinter

17
  1. 사용 rename

    find . -type f -name "* *.xml" -exec rename "s/\s/_/g" {} \;

    또는 $1

    find "$1" -type f -name "* *.xml" -exec rename "s/\s/_/g" {} \;
  2. 사용 mv

    find . -type f -name "* *.xml" -exec bash -c 'mv "$0" "${0// /_}"' {} \;

    또는 $1

    find "$1" -type f -name "* *.xml" -exec bash -c 'mv "$0" "${0// /_}"' {} \;

왜 그런지 모르겠지만 주어진 명령이 나를 위해 작동하지 않습니다. 오류 및 출력이 표시되지 않습니다.
krishna

@krishna 수정, 죄송합니다
AB

1
이름 바꾸기가 나를 위해 일했습니다. 주먹 범프!
Brian Piercy

1

이것은 같은 문제에 직면하면서 찾은 방법입니다.

for f in *; do mv "$f" `echo $f | tr ' ' '_'`; done

내 SSL 인증서를 자동으로 업데이트하기 위해 bash 스크립트 파일을 작성 중이었습니다.


1

사용 rename:

rename 's/\s/_/g' ./*.xml

필요 없음 find:)


1
후행 g를 정규 표현식에 추가하면 완벽하게 작동합니다. 의 / \ S / _ / g '
jbrahy

좋은 팁, 감사합니다 :)
Jan Werkhoven
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.