여러 개의 txt 파일이 있는데 이를 소문자, 알파벳 순으로 한 줄에 한 단어씩 출력하고 싶습니다. tr
다음과 같이 파이프라인에서 여러 명령을 사용하여 이 작업을 수행할 수 있습니다.
tr -d '[:punct:]' <doyle_sherlock_holmes.txt | tr '[:upper:]' '[:lower:]' | tr ' ' '\n'
한 번의 스캔으로 완료할 수 있나요? 이를 위해 C 프로그램을 작성할 수도 있지만 tr
, sed
또는 를 사용하여 awk
이를 수행할 수 있는 방법이 있는 것 같습니다 perl
.
답변1
여러 번역을 결합할 수 있지만(로케일 관련 세트가 겹치는 복잡한 경우 제외) 삭제와 번역을 결합할 수는 없습니다.
<doyle_sherlock_holmes.txt tr -d '[:punct:]' | tr '[:upper:] ' '[:lower:]\n'
더 복잡한 도구의 경우 두 번의 호출이 tr
한 번의 호출보다 빠를 수 있지만 이는 입력 크기, 다양한 문자의 비율, 도구 구현 tr
및 경쟁 도구, 운영 체제, 코어 수 등에 따라 크게 달라집니다.
답변2
예. tr
ASCII 로케일에서 이 작업을 수행 할 수 있습니다.(GNU의 경우 어쨌든 tr
이것이 유일한 권한입니다). POSIX 클래스를 사용하거나 8진수로 각 문자의 바이트 값을 참조할 수 있습니다. 범위에 걸쳐 변환을 분할할 수도 있습니다.
LC_ALL=C tr '[:upper:]\0-\101\133-140\173-\377' '[:lower:][\n*]' <input
위 명령은 모든 대문자를 소문자로 변환하고, 소문자를 완전히 무시하고, 다른 모든 문자를 개행 문자로 변환합니다. 물론 빈 줄이 많이 생길 것입니다. 이 경우 압착 반복 스위치가 유용할 수 있지만 tr
-s
to 변환과 함께 사용하면 결국 대문자도 압착하게 됩니다. 이렇게 하면 여전히 다음과 같은 두 번째 필터가 필요합니다.[:upper:]
[:lower:]
LC... tr ... | tr -s \\n
...또는...
LC... tr ... | grep .
...결국 이렇게 하는 것보다 훨씬 편리해집니다...
LC_ALL=C tr -sc '[:alpha:]' \\n <input | tr '[:upper:]' '[:lower:]'
...이것은 -c
알파벳 문자의 2개의 보수를 단일 개행 문자로 순차적으로 압축한 다음 파이프의 다른 쪽에서 위에서 아래로 변환을 수행합니다.
그렇다고 이러한 성격의 범위가 유용하지 않다는 것은 아닙니다. 이 같은:
tr '\0-\377' '[1*25][2*25][3*25][4*25][5*25][6*25][7*25][8*25][9*25][0*]' </dev/random
...입력 바이트를 해당 값의 확산 스펙트럼 내의 모든 숫자로 변환하므로 매우 편리할 수 있습니다. 낭비하지 말고, 원하지도 마세요.
변환을 수행하는 또 다른 방법에는 dd
.
tr '\0-\377' '[A*64][B*64][C*64][D*64]' </dev/urandom |
dd bs=32 cbs=8 conv=unblock,lcase count=1
dadbbdbd
ddaaddab
ddbadbaa
bdbdcadd
작업 과 변환을 동시에 dd
수행할 수 있으므로 대부분 의 작업을 여기에 맡길 수도 있습니다. 그러나 이는 단어당 바이트 수를 정확하게 예측할 수 있거나 적어도 각 단어에 공백을 미리 채워 예측 가능한 바이트 수를 달성할 수 있는 경우에만 유용합니다. 왜냐하면 이것이 각 블록 공간의 후행 끝을 차지하기 때문입니다.unblock
lcase
unblock
답변3
다음은 몇 가지 방법입니다.
GNU
grep
Sumtr
: 모든 단어를 찾아 소문자로 만듭니다.grep -Po '\w+' file | tr '[A-Z]' '[a-z]'
GNU grep 및 perl: 위와 동일하지만 Perl은 소문자 변환을 처리합니다.
grep -Po '\w+' file | perl -lne 'print lc()'
perl: 모든 알파벳 문자를 찾아 소문자로 인쇄합니다(@steeldriver에게 감사드립니다):
perl -lne 'print lc for /[a-z]+/ig' file
sed: 문자나 공백이 아닌 모든 문자를 제거하고 모든 알파벳 문자를 소문자 버전으로 바꾸고 모든 공백을 줄 바꿈으로 바꿉니다. 이는 모든 공백이 공백이고 탭이 없다고 가정합니다.
sed 's/[^a-zA-Z ]\+//g;s/[a-zA-Z]\+/\L&/g; s/ \+/\n/g' file