한 줄에 한 단어씩 가져오기 위해 패턴을 바꾸고 여러 단어가 포함된 파일을 정리하려고 합니다.
다음 명령줄을 사용하여 결과를 얻을 수 있습니다.
sed -e '/^[[:space:]]*$/ d' \ # remove empty line
-e 's/^[[:space:]]*//' \ # remove white space at the beginning
-e 's/[[:space:]]*$//' \ # remove white space at the ending (EOL)
-e 's/[[:space:]][[:space:]]*/\n/g' \ # convert blanks between words to newline
-e '$a\' # add a newline if missing at EOF
-e ..... # replace other patterns.
(마지막 표현은파일 끝에 개행 문자를 추가하는 방법은 무엇입니까?)
아이디어는 작은 sed 프로그램을 사용하여 파일을 처리하고(예: 특정 패턴 교체) 동시에 파일 형식을 지정하는 것입니다.
표현을 줄이기 위해 다른 sed 함수를 사용할 수 있다고 확신합니다.
인사
답변1
당신은 그것을 사용할 수 있습니다 tr
:
tr -s "[[:blank:]]" "\n" < file | grep .
문자 [:blank:]
클래스에는 가로 공백이 모두 포함됩니다. -s
여러 문자의 발생을 하나로 압축 하거나 줄입니다.
grep
빈 줄이 있으면 제거하세요 .
답변2
이 시도
sed -e 's/[[:space:]]/\n/g' | grep -v '^$'
둘 다 사용 grep
하지만 sed
괜찮기를 바랍니다. ( sed
보통 사용하는 시스템이 있는 경우 grep
)
답변3
sed는 아니지만:
gawk length RS='[[:space:]]+' file
일련의 공백을 레코드 구분 기호로 처리하고 널이 아닌 모든 레코드를 인쇄합니다.
답변4
OP는 "단일 호출" 사용을 고집하는 것 같으므로 sed
다음과 같습니다.
부분적인 패턴 공간을 숨기는 비단어 분할 방법:
sed -n -e 's/^\W*//' -e 's/\(\W\+\)/\n/gp' words.txt
편집: @don_crissti가 지적했듯이 이 솔루션은 한 줄에 단독으로 나타나는 단어를 먼저 인쇄할 수 없고 파일에 종료 문자가 없는 경우 출력 끝에 개행을 삽입할 수 없기 때문에 완전하지 않습니다. 개행. 이 문제를 해결하려면 아래의 매우 보기 흉한 솔루션을 참조하세요.
가장 큰 문제 sed
는 각 표현식이 작동하는 패턴 공간이 -e
항상 라인으로 정의된다는 것입니다. 개행 문자를 삽입하여 첫 번째 표현식과 다음 표현식 사이의 행 구조를 변경하면 처리된 데이터에서 다음 표현식이 실행되지 않습니다.
설명하다:
먼저, 각 줄은 선행 공백(있는 경우)에 대해 처리됩니다. 그것만으로 구성된 라인은 패턴 공간의 라인 길이를 유지하면서 빈 라인이 됩니다.
두 번째 부분의 핵심은 일부 사람들이 "grep 모드"라고 부르는
-n
옵션과 (인쇄) 명령의 조합입니다 . 이는 기본적으로 일치하거나 변경된 행만 인쇄하는 효과가 있습니다. 출력이 인쇄되는 것을 방지하고 일치 및/또는 변경된 행이 인쇄되도록 합니다. 이렇게 하면 완전히 빈 줄이 인쇄되는 것을 피할 수 있습니다. 예상 되니까p
sed
-n
p
\W\+
마지막 하나단어가 아닌 문자와 빈 줄은 제외됩니다. 이전에는 표현식과 일치했을 선행 공백이 빈 줄로 바뀌었습니다.편집 : 설명하는 것을 잊었습니다부족첫 번째 표현에 있는 명령의 의미
p
도 중요합니다. 각 표현식에는 일반적으로 패턴 공간이 인쇄되어 이를 인쇄한 표현식만큼 각 행을 볼 수 있으며, 해당 표현식 중 하나라도 주어진 행을 변경했다면 변경 사항이 있을 것입니다. 그러나 패턴 공간이 인쇄되지 않더라도 변경된 형식으로 후속 표현식에 전달되므로 마지막 표현식만 표시되는 동안 하나의 입력 줄에서 시작되는 단일 파이프에서 실행되는 표현식을 연결할 수 있습니다.
단어를 공백이 아닌 문자의 시퀀스로 생각하는 것을 선호한다면 음... 그렇습니다. 그러나 그 정의는 단순한 단어 이상의 것을 포함합니다. 이는 단어가 아니라 공백이 아닌 시퀀스입니다. 그러나 이들을 일치시키고 단어 대신 별도의 줄에 인쇄하려면 다음을 사용하십시오.
sed -n -e 's/^\s*//' -e 's/\(\s\+\)/\n/gp' words.txt
0바이트 교체 방법
편집: @don_crissti가 단일 단어가 있고 EOF에 줄 바꿈이 누락된 줄에서 지적한 문제는 다음 명령을 사용하여 해결할 수 있습니다. 너무 길지는 않지만 터무니없을 정도로 해킹적이라는 것 외에도 내가 알고 있는 결함이 하나 이상 있습니다. 즉, 해당 줄에 여러 단어가 있으면 한 줄만 있는 파일에서는 작동하지 않는다는 것입니다. 이 문제를 해결하기 위한 한 가지 아이디어는 마지막 줄이 첫 번째 줄인지 확인하기 위해 분기를 추가하는 것입니다. 이는 프로그램을 더 복잡하게 만듭니다(그리고 시간이 더 많이 걸립니다 :D). 이것은 명령입니다:
sed -rn 's/(\b|\W)+/\x0/g; s/^\x0//; s/\x0$//; s/\x0/\n/g; /^$/d; $! p; $ { s/$/\n/; P }'
설명하다:
이 명령은 다음 프로세스 중에 작동합니다.
첫째, 단어가 아닌 문자뿐만 아니라 줄의 끝과 시작(문자가 아닌 너비가 0인 어설션)과 같은 단어 경계가 0바이트로 대체됩니다. 여기에는 단어 경계와 그에 인접한 비단어 문자 시퀀스(해당 위치)도 포함됩니다.
그런 다음 각 줄의 시작과 끝에서 0바이트가 제거됩니다.
그런 다음, 중간에 있는 각 0바이트가 개행 문자로 대체됩니다.
결과로 나타나는 빈 줄은 패턴 공간에서 제거됩니다. 현재로서는 순수한 빈 줄이 없습니다.
현재 패턴 공간의 주소가 마지막 주소가 아닌 경우(즉, 마지막 줄에 있지 않은 경우) 간단히 해당 줄을 인쇄합니다.
데이터 끝에서 우리는 2개의 명령을 실행합니다:
원래 데이터가 개행으로 끝나지 않았더라도 최소한 1개의 종료 개행을 갖기 위해 현재 패턴 공간의 끝에 개행을 추가합니다.
현재 패턴 공간에 포함된 첫 번째 줄바꿈만 인쇄합니다. 여기에는 최대 2개의 줄바꿈이 있습니다.
그건 그렇고, 내가 본 이 문제에 대한 가장 간단한 해결책은 다음과 같습니다.
grep -o '\w\+' words.txt
또는 공백으로 시작하는 줄을 처리할 필요가 없는 경우:
fmt -1 words.txt