파일에서 새 줄, 공백 제거

파일에서 새 줄, 공백 제거

내 디렉토리에는 많은 파일이 있으며 각 파일은 다음과 같습니다.

AAA 
AA

AAAAAA
A


AAAA

나는 이것으로 끝내고 싶습니다 :

AAAAAAAAAAAAAAAA

내가 실행할 때 이런 식으로 :

find ./ -name '*' -exec wc -m {} +

계산되는 새 줄/공백 수에 따라 20+ 대신 16을 반환합니다.

기본적으로 편지가 아닌 이상 파일에서 모든 것을 제거하고 싶습니다.

답변1

파일에서 모든 개행 문자를 제거하면(마지막 문자까지 포함) 텍스트 파일에는 개행 문자로 구분된 일련의 텍스트 줄이 포함되어 있으므로 더 이상 텍스트 파일이 아닙니다(파일이 비어 있지 않는 한).

이제 @Kusalanada가 말했듯이 알파벳 문자(모든 알파벳)를 제외한 모든 문자를 제거하려면 POSIXly를 사용할 수 있습니다 tr -cd '[:alpha:]'.

이제 불행히도 일부 tr구현 에서는GNU 포함tr, 멀티바이트 문자에서는 작동하지 않습니다. UTF-8 로케일에서는 ASCII 문자를 제외한 모든 문자를 의미합니다.

GNU 시스템에서는 멀티바이트 문자를 지원하는 GNU awk또는 GNU를 사용할 수 있습니다 .sed

<file sed 's/[^[:alpha:]]//g' | tr -d '\n'

<file awk -v ORS= '{gsub(/[^[:alpha:]]/, ""); print}'

구문은 GNU에만 국한되지 않지만 멀티바이트 문자를 지원하지 않는 일부 비GNU sed/구현을 찾을 수 있습니다. awkGNU sed/ 는 awk적어도 유효한 문자를 형성하지 않는 바이트 시퀀스를 제거하지 않습니다(예: printf 'à b \200\n'UTF-8 로케일로 출력).

uconvICU 프로젝트를 통해 다음을 수행할 수 있습니다.

<file uconv -i -x '[^[:Letter:]]>;'

이는 디코딩할 수 없는 입력을 건너뛰도록 -i지시합니다 .uconv

그러나 이는 UTF-8 데이터에만 작동합니다. 로케일에 따라 문자인지 아닌지를 결정하는 대신 유니코드 문자 속성(유니코드의 일부 버전)을 사용한다는 점에 유의하세요.

GNU를 사용하면 grep다음을 사용할 수 있습니다.

<file grep -o '[:alpha:]' | tr -d '\n'

또는 PCRE 지원으로 빌드하는 경우(유니코드 속성 사용):

<file grep -Po '\pL' | tr -d '\n'

GNU의 경우 awk잘못된 입력을 건너뛰는 또 다른 방법은 다음을 사용하는 것입니다 RS.

<file gawk -v RS='[[:alpha:]]' -v ORS= '{print RT}'

gawk파일을 제자리에서 수정하려면 다음 모듈을 사용할 수 있습니다 inplace.

gawk -i /usr/share/awk/inplace.awk gawk -v RS='[[:alpha:]]' -v ORS= '{print RT}' file

사용하지 마세요-i inplace현재 작업 디렉터리(as or)에서 확장 기능을 먼저 gawk로드 하려고 하면 누군가가 해당 디렉터리에 악성 코드를 심었을 수 있습니다. 시스템과 함께 제공되는 확장 프로그램 의 경로 는 다를 수 있습니다. 출력을 참조하세요.inplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

답변2

-name '*'원하는 만큼 처리할 필요는 없습니다.모든파일( *어쨌든 모든 파일과 일치하므로 아무런 차이가 없습니다). 그러나 아마도 -type f(디렉토리 등이 아닌) 일반 파일 만 다루고 싶을 것입니다 .

문자가 아닌 것을 제거하려면 다음을 사용할 수 있습니다.

tr -cd '[:alpha:]' <file

-c지정된 문자 세트를 보완 하고 [:alpha:]알파벳 문자만 일치시킵니다. 일치하는 -d문자를 삭제함을 나타냅니다 tr.

따라서 실행하려는 명령은 다음과 같습니다.

tr -cd '[:alpha:]' <file | wc -m

각 파일마다.

직접 수행 하기에는 너무 복잡하므로 find인라인 스크립트를 사용해야 합니다.

find . -type f -exec sh -c '
    for pathname do
        tr -cd "[:alpha:]" <"$pathname" | wc -m
    done' sh {} +

여기서 인라인 sh -c스크립트는 배치 파일 경로 이름을 매개변수로 가져옵니다 find. 파이프라인은 각 파일에 대해 실행됩니다.

답변3

사용행복하다(이전 Perl_6)

~$ raku -e 'S:g/ <-alpha> //.put given lines;'  file

#OR

~$ raku -e 'S:g/ <- :L > //.put given lines;'  file

또는:

~$ raku -e 'S:g/ <-alpha> //.put given slurp;'  file

#OR

~$ raku -e 'S:g/ <- :L > //.put given slurp;'  file

Raku는 내장된 유니코드에 대한 고급 지원을 제공하므로 멀티바이트 문자를 계산하기 위해 외부 라이브러리를 로드할 필요가 없습니다. 정규식 문자 클래스는 :L유니코드 문자를 나타내며, <- :L >대체 시 유니코드 문자를 "제외한" 모든 문자가 제거된다는 의미입니다.

입력 예(첫 번째 줄에는 ~6개의 공백이 있고, 여섯 번째 줄에는 ~12개의 공백이 있습니다):

AAA     
AA1234

ÀÁÂÃÄÅÆ
1234
       
AAAA

예제 출력:

AAAAAÀÁÂÃÄÅÆAAAA

문자 수를 계산합니다.

~$ raku -e 'S:g/ <- :L > //.raku.put given lines;'  file
"AAAAAÀÁÂÃÄÅÆAAAA"
~$ raku -e 'S:g/ <- :L > //.chars.put given lines;'  file
16
~$ raku -e 'S:g/ <- :L > //.comb.elems.put given lines;'  file
16

https://docs.raku.org/언어/unicode
https://raku.org

관련 정보