잘못된 곳에서 끊어진 줄을 어떻게 고칠 수 있습니까?


11

내 텍스트 파일은 다음과 같습니다

This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.

소문자로 시작하는 줄 다음에 오는 줄의 후행 줄 바꿈 문자를 제거하고 싶습니다.

따라서 다음과 같아야합니다.

This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.

어떻게해야합니까?

편집 : 여기에 정말 좋은 답변이 있지만 가장 효과 적이고 빠른 첫 번째 답변을 선택했습니다 . 정말 고마워요!


1
유액? 문제는 적절한 문장 분리 규칙을 실제로 명시하지 않는다는 것입니다. 문장 끝 문장 부호를 포함하여 모든 것을 한 줄에 넣기를 원하십니까? 그러나 문장이 길고 디스플레이 창의 가장자리에서 떨어지면 어떻게해야합니까?
jamesqf

1
당신이 정말로 무엇을 해결하려고하는지 궁금합니다. 아마도 마크 다운 형식을 사용해야합니까?
와일드 카드

@JeffSchaller 미리 알림 주셔서 감사합니다! 나는 어떻게 든 놓쳤다. :)

답변:


7

시험

awk '$NF !~ /\.$/ { printf "%s ",$0 ; next ; } {print;}' file

어디

  • $NF !~ /\.$/ 마지막 요소가 점으로 끝나지 않는 라인 일치,
  • { printf "%s ",$0 이 줄을 후행 공백으로 인쇄하고 줄 바꿈없이
  • next ; } 다음 줄을 가져와
  • {print;} 인쇄하십시오.

sed옵션 이있을 것이라고 확신 합니다.

참고 : 점으로 끝나는 줄에서 작동하지만 대문자로 시작하는 문장의 조건은 병합되지 않습니다. Stéphane Chazelas의 답변을 참조하십시오.


당신이 영리한 것을 좋아한다면 (많은 것은 아님)awk 'ORS=$NF~/\.$/?"\n":" "'
dave_thompson_085

10

awk:

awk -v ORS= '{print (NR == 1 ? "" : /^[[:lower:]]/ ? " " : RS) $0}
             END {if (NR) print RS}'

즉, 각 행에 레코드 구분 기호를 추가하지 마십시오 (또는 비어 있음). 그러나 첫 번째 행이 아니고 현재 행이 소문자로 시작하지 않으면 현재 행 앞에 레코드 구분 기호를 추가 하십시오. 그렇지 않으면 첫 번째 행을 제외하고 공백 문자를 앞에 추가하십시오.


이것을 실행하면 몇 쌍의 단어가 연결됩니다. 예를 들어 And thisone issomehow, broken intomany.나도 몰라 awk하지만 라인과 결합되어야한다 <space>이외에 RS? 아니면이 사용자 오류입니까?
B Layer

@BLayer, 감사합니다. 지금 수정해야합니다.
Stéphane Chazelas

문제 없어요. 11 개의 공감대가 어디에서 왔는지 궁금합니다. 사람들이 당신이 항상 옳다고 생각하게하는 것이 좋을 것입니다. ;)
B 레이어

4

펄에서 :

#!/usr/bin/perl -w
use strict;
my $input = join("", <>);
$input =~ s/\n([a-z])/ $1/g;
print $input;

기술적으로 "줄 바꾸기 문자 뒤에 소문자"를 "공백과 소문자로"바꾸고 싶었습니다. 위의 펄 스크립트의 핵심은 다음과 같습니다.

  1. 입력을 문자열로 읽습니다 input.
  2. input검색 및 바꾸기 작업의 결과가되도록 변수를 업데이트하십시오 .
  3. 새 값을 인쇄하십시오.

1
좋은 것 !! 한 줄짜리로 번역되고 perl -0777 -pe 's/\n([a-z])/ $1/g'GNU sed를 사용하여 비슷하게 수행 할 수 있습니다 sed -zE 's/\n([a-z])/ \1/g'(입력에 null 문자가 없다고 가정)
Sundeep

3
@Sundeep 또는 perl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'ASCII 문자로 제한되지 않습니다.
Stéphane Chazelas

4

으로 sed당신이 사용할 수있는 N;P;D사이클 (그래서 항상에 관한 것은 패턴 공간에 두 개의 라인을 가지고와 줄 바꿈 후 첫 번째 문자가 소문자 인 경우 공백으로 줄 바꿈 대체)와 t동부 표준시 - 각 후 그런 식으로 s당신이주기를 다시 시작 ubstitution를 :

sed -e :t -e '$!N;/\n[[:lower:]]/s/\n/ /;tt' -e 'P;D' infile

1
나는 여기에서 무슨 일이 일어나고 있는지 알지만 확장 된 대답은 sed 루프와 패턴 공간을 자주 사용하지 않는 사람들에게 도움이 될 것입니다.
Joe

@Joe- "패턴 공간을 자주 사용하지 않는다"는 것은 무엇을 의미 합니까? 여기에서 거의 모든 작업이 수행됩니다. 보류 공간은 "저장 공간"입니다. 데이터가있는 동안에는 아무것도 할 수 없습니다. 어쨌든, 나는 방법을 자세히 설명했다 주기가 여기서 일하는 내가 다시 가서하지 않도록. 여기서 차이는 가장 큰 것입니다. 어떤 것이 교체되었는지 여부를 확인하는 것입니다. 테스트가 성공하면 스크립트 상단으로 분기합니다. 그렇지 않으면 아무것도 교체 되어 실행 되지 않았다는 의미 입니다. 여전히 확실하지 않은 경우 알려주십시오. N;P;DtP;D
don_crissti

3

사용 sed하여 fmt:

$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt
This is one sentence that is broken.

However this is a good one.

And this one is somehow, broken into many.

sed 스크립트는 대문자로 시작하는 모든 행 앞에 개행을 삽입합니다 (첫 번째 입력 행 제외). sed그런 다음 fmt결과 단락을 재구성하기 위해 출력으로 파이프됩니다 .

또는 par설치 한 경우 사용 하십시오. 또 다른 단락 재구성 기이지만보다 fmt많은 기능과 옵션을 제공하는 것보다 훨씬 기능이 뛰어납니다.

각 단락 사이에 빈 줄이 있습니다. 단락 하나 이상의 빈 줄로 서로 분리 해야 합니다. 빈 줄이 없으면 전체 입력 샘플이 단일 다중 문장 단락으로 다시 포맷됩니다. 예 :

$ fmt input.txt
This is one sentence that is broken.  However this is a good one.
And this one is somehow, broken into many.

다시 포맷 한 후 빈 줄을 제거해야하는 경우 sed다시 연결하면됩니다. 그러나 원래 입력에 있었던 줄을 포함하여 모든 빈 줄이 제거됩니다. 예 :

$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt | sed -e '/^$/d'
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.

3

이를 수행 할 수있는 다른 방법은 다음과 같습니다.

perl -lpe '$\ = /\.$/ ? $/ : $"' data

여기서 : $\=> ORS, $/=> IRS= \n, $"=space

perl -pe '$_ .= <>, eof or redo if s/[^.]\K\n/ /' data

sed -e '
   :a
      /\.$/!N
      s/\n/ /
   ta
' data

2

파이썬 3

import re
print(re.sub(r'\n([a-z])', r' \1', open('file.txt').read(), flags=re.MULTILINE))

이것은 Jeff의 답변 과 동일한 정규 표현식 / 대체입니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.