Bash - 새 줄을 공백으로 바꾸기 전에 대시와 새 줄을 제거하세요.

Bash - 새 줄을 공백으로 바꾸기 전에 대시와 새 줄을 제거하세요.

다음 형식의 텍스트 파일이 많이 있습니다.

Lorem ipsum dolor sit amet,
consetetur sadipscing elitr,
sed diam nonumy eirmod tempor
invidunt ut labore et dolore
magna aliquyam erat, sed diam
voluptua. - At vero eos et accu-
sam et justo duo dolores et ea
rebum. - Stet clita kasd guber-
gren, no sea takimata sanctus
est Lorem ipsum dolor sit amet.

명령줄에서 연속 텍스트로 인쇄하되 줄 끝의 음절 구분을 제거하는 방법:

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. - At vero eos et accusam et justo duo dolores et ea rebum. - Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

tr '\n' ' '줄 바꿈을 공백으로 변환하는 데 사용할 수 있습니다

문제는 tr한 문자만 교체할 수 있고 -\n이를 미리 제거하려면 몇 가지 명령이 필요하다는 것입니다.Bash 명령줄에서 이를 어떻게 달성할 수 있나요?

답변1

사용 awk:

awk -F'-$' '{ printf "%s", sep $1; sep=/-$/?"":OFS } END{ print "" }' infile

를 사용하여 -F'-$'우리는 정의합니다.에프생산하다에스쪼개는 도구이렇게 하고 첫 번째 필드를 취하면 $1해당 하이픈이 있는 줄에 대해 항상 하이픈이 없는 줄이 생기고, 하이픈이 없는 줄은 항상 갖게 됩니다. 해당 하이픈이 없으면 항상 전체 행을 소유하게 됩니다.

그런 다음 우리는 그것을 인쇄합니다sep사이에 있지만 현재 줄이 하이픈으로 끝나면 다음 줄을 빈 문자열로 읽을 때 변경되고, 그렇지 않으면 OFS(산소산출에프생산하다에스쪼개는 도구, 기본값은 공백 문자입니다).

존재하다END{...}막힌이를 만들기 위해 마지막 개행 문자를 추가하고 있습니다.POSIX 텍스트 파일, 추가하고 싶지 않다면 해당 섹션을 삭제하세요.


sed, 또는 다음을 사용하세요 .

sed ':loop /-$/N;s/-\n//;t loop; N;s/\n/ /;t loop' infile
  • : 반지
    • 줄이 하이픈( test 사용 /-$/)으로 끝나면 다음을 읽어보세요.질소ext 라인을 삭제하고 "hyphen + \newline"을 빈 문자열로 바꿉니다.
      교체가 성공하면( test 사용 t) 레이블로 점프합니다.반지다음 줄을 처리하고 나머지 코드 실행을 건너뜁니다.
    • 그렇지 않으면 읽어주세요.질소ext 행을 삭제하고 \n이 두 행 사이에 포함된 줄바꿈을 공백 문자로 바꿉니다.
      여기에서도 교체가 성공하면 레이블로 이동합니다.반지그리고 다음 줄을 처리합니다.

답변2

또 다른 perl해결 방법(마지막 줄이 -문자로 끝나지 않는다고 가정):

perl -pe 's/-\n//; s/\n/ / if !eof'

sed또는 와 달리 레코드 구분 기호는 다음을 사용하여 awk직접 조작할 수 있습니다 . perl따라서 일치하는 항목이 있으면 삭제하기 쉽습니다 -\n. s/\n/ / if !eof그러면 마지막 줄을 제외하고 나머지 개행 문자는 공백으로 대체됩니다.

끝에 추가 공백이 있어도 괜찮다면 해당 if !eof섹션을 제거할 수 있습니다.

답변3

  1. 줄 끝의 하이픈에 사용된 대시를 제거합니다(하이픈으로 연결된 줄을 절차의 다음 줄에 연결).
  2. 줄 바꿈을 공백으로 바꾸십시오.
sed -e ':again' -e '/[[:alpha:]]-$/ { N; s/-\n//; b again; }' file |
paste -s -d ' ' -

하이픈으로 연결된 줄을 사용합니다 sed. 이는 줄 끝에 대시와 문자가 있는 줄을 감지하여 이를 수행합니다. [[:alpha:]]대시 앞을 일치 시키면 하이픈에 사용된 대시만 제거된다는 확신이 듭니다. 그런 다음 N(리터럴 줄 바꿈 삽입)을 사용하여 다음 줄을 읽고 삭제 -\n한 다음 추가 하이픈이 있는지 결합된 줄을 다시 확인합니다( b again태그 분기가 에 대한 것임 again).

그런 다음 이 paste유틸리티를 사용하여 모든 줄을 하나의 연속된 줄에 붙여넣습니다. 이 -s옵션은 모든 행을 한 줄로 연결하고 -d ' '행을 연결할 때 사용되는 구분 기호를 지정하는 데 사용됩니다.

tr '\n' ' '내가 사용한 명령 대신 이것을 사용할 수 있지만 paste그렇게 하면 종료되지 않은 줄이 제공됩니다(끝에 개행 없음).

답변4

사용POSIX sed스트림 편집기 유틸리티.

sed -e ':a
  $!N
  s/-\n//;ta
  s/\n/ /;ta
' file

그리고유틸리티에서는 다음 줄을 읽는 루프를 설정하고 ORS를 작동하여 이전 줄을 인쇄합니다.

awk '
{
  while (getline t > 0) {
    ORS = sub(/-$/, "") ? "" : OFS
    print
    $0 = t
  }
  ORS = RS
}
1' file

$\현재 레코드를 기반으로 출력 레코드 구분 기호를 다시 정렬할 수 있습니다.

perl -lpe '
  $\ =   eof  ? $/
     : s/-$// ? $,
     :          $"
     ;
' file
  • $/입력 레코드 구분 기호이며 기본값은 개행입니다.
  • $"따옴표로 묶인 배열 요소 구분 기호이며 기본값은 공백입니다.
  • $,출력 필드 구분 기호이며 기본값은 빈 문자열입니다.

관련 정보