내 디렉토리에는 많은 파일이 있으며 각 파일은 다음과 같습니다.
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
/구현을 찾을 수 있습니다. awk
GNU sed
/ 는 awk
적어도 유효한 문자를 형성하지 않는 바이트 시퀀스를 제거하지 않습니다(예: printf 'à b \200\n'
UTF-8 로케일로 출력).
uconv
ICU 프로젝트를 통해 다음을 수행할 수 있습니다.
<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
로드 하려고 하면 누군가가 해당 디렉터리에 악성 코드를 심었을 수 있습니다. 시스템과 함께 제공되는 확장 프로그램 의 경로 는 다를 수 있습니다. 출력을 참조하세요.inplace
inplace
inplace.awk
inplace
gawk
gawk '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