디렉터리 이름에서 개행 문자를 반복적으로 제거합니다.

디렉터리 이름에서 개행 문자를 반복적으로 제거합니다.

다음과 같은 이름을 가진 여러 디렉터리가 있습니다.

여기에 이미지 설명을 입력하세요.

재귀적으로 끝에서 줄바꿈을 제거하고 싶습니다.

나는 확인했다반복적으로 디렉터리 이름 바꾸기

나도 확인했다파일 이름에서 개행 문자 제거

제안된 솔루션은 다음과 같습니다.

find -name $'*\n*' -exec rename  $'s|\n| |g' '{}' \;

하지만 내 경우에는 find -name $'*\n*'아무것도 반환되지 않습니다. 삭제하면 $디렉토리를 찾을 수 있습니다

% find . -name '*\n*'
./second?
% find . -name '*\r*'
./third?
./first?

그러나 실행하면 find . -name '*\n*' -exec rename $'s|\n| |g' '{}' \;디렉토리 이름이 바뀌지 않습니다. 나는 find . -name $'*\n*' -exec rename $'\n' ' ' {} \;또한파일 이름에서 개행 문자를 반복적으로 제거합니다.. 또한 디렉토리 이름을 바꾸지 않았습니다.

어떡해?

답변1

전에도 그렇게 말했잖아

printf "%q\n" *프로그램first$'\342\200\251' second$'\342\200\251' third$'\342\200\251'

이것은 $'\342\200\251'일반적인 개행 문자이지만유니코드 U+2029 단락 구분 기호, UTF-8로 인코딩됩니다. 출력에는 8진수 바이트가 있습니다 e2 80 a9.

그렇기 때문에 find -name $'*\n*'일치하지 않습니다. 달러가 없으면 문자만 일치하는 것과 같습니다 -name '*\n*'. 이러한 모드는 다음 문자를 특별하지 않게 만드는 쉘 전역 모드일 뿐입니다. 예를 들어 별표 하나만 일치하는 반면 모든 항목은 일치합니다. 특별한 건 아니니까 그냥 놔두세요.-name '*n*'nsecond-name\\**n\n

이제 그것이 무엇인지 알았으므로 개행 문자를 제거한 것처럼 제거할 수 있습니다. Perl 이름 바꾸기를 통해 File::Rename제거해야 합니다 (예: 다음을 사용).

find . -depth -name $'*\342\200\251' \
       -execdir rename -v $'s|\342\200\251||g' '{}' +

-depth리프가 있는 브랜치 이전에 리프의 이름을 바꿔야 하며 -execdir(표준은 아니지만 일반적임) rename이름 바꾸기를 위해 파일의 기본 이름만 사용하여 파일이 포함된 디렉터리에서 리프를 호출해야 합니다.

... rename -v 's|\342\200\251||g'Perl 표현식이고 Perl이기 때문에 작동해야 합니다.하다백슬래시 해석도 자체적으로 이스케이프됩니다.

가지고 있는 명령이 rename $'s|\n| |g'공백으로 대체되지만 이름 끝에 문자가 있기 때문에 혼란스럽기도 합니다.

답변2

그리고 zsh:

autoload zmv # best in ~/.zshrc
zmv -v $'(**/)(*[\n\u2029]*)(#qD)' $'$1${2//[\u2029\n]}'

두 개의 개행 문자(U+000A)를 제거하려면 또는단락 구분 기호문자(U+2029).

또는:

zmv -v $'(**/)(*[[:cntrl:]]*)(#qD)' $'$1${2//[[:cntrl:]]}'

모든 제어 문자를 제거합니다.

그러나 U+2029의 분류 여부는 cntrl시스템에 따라 다릅니다. Ubuntu 20.04에서는 작동하지만 FreeBSD 12.2에서는 작동하지 않습니다. 실행 [[ $'\u2029' = [[:cntrl:]] ]] && echo yes하여 시스템을 확인하십시오.

관련 정보