sed를 사용하여 줄 바꿈 (\ n)을 바꾸려면 어떻게해야합니까?


1370

명령을 사용하여 줄 바꿈 ( " \n")을 공백 ( " ")으로 바꾸려면 어떻게 sed해야합니까?

실패했습니다.

sed 's#\n# #g' file
sed 's#^$# #g' file

어떻게 고치나요?


27
tr위의 예는 줄 바꿈을 공백으로 바꿉니다. 위의 예에서 tr은 작동합니다. 그러나 나중에 제한 될 것입니다.
Angry 84

9
tr질문자가 그의 예제에 표시된 것처럼 각 줄 바꿈을 공백으로 바꾸려고했기 때문에 작업에 적합한 도구. 개행의 대체는 독창적 sed이지만 쉽게 수행 할 수 있습니다 tr. 이것은 일반적인 질문입니다. 정규식 대체를 수행하는 tr것은에 의해 수행되는 것이 아니라에 의해 수행됩니다 sed. 이는 다른 질문에 대한 올바른 도구입니다.
Mike S

3
"tr"은 줄 바꿈`tr -d '\ n'`을 삭제할 수도 있지만,보다 보편적 인`tr -d '\ 012 \ 015'`인 리턴을 삭제할 수도 있습니다.
안토니

2
경고 : "tr"은 Linux와 이전 Solaris 시스템 (EG sol5.8) 사이의 문자 범위와 관련하여 다르게 작동합니다. EG :`tr -d 'az'`및`tr -d '[az]'`. 이를 위해 차이가없는 "sed"를 사용하는 것이 좋습니다.
안토니

2
@ Mikes 답변 주셔서 감사합니다. 따라 tr '\012' ' '와 함께 echo. 그렇지 않으면 파일의 마지막 줄 바꿈도 삭제됩니다. tr '\012' ' ' < filename; echo트릭을 수행합니다.
Bernie Reiter

답변:


1513

이 솔루션을 GNU와 함께 사용하십시오 sed.

sed ':a;N;$!ba;s/\n/ /g' file

전체 파일을 루프로 읽은 다음 줄 바꿈을 공백으로 바꿉니다.

설명:

  1. 를 통해 라벨을 만듭니다 :a.
  2. 를 통해 현재와 다음 줄을 패턴 공간에 추가합니다 N.
  3. 우리가 마지막 줄에 이전하는 경우, 생성 된 레이블 분기 $!ba( $!마지막으로 줄 바꿈이 있어야 수단은 마지막 줄에 그것을 할 수 없습니다).
  4. 마지막으로 대체는 모든 개행을 패턴 공간 (전체 파일)의 공백으로 바꿉니다.

다음은 BSD 및 OS X에서 작동하는 크로스 플랫폼 호환 구문입니다 sed( @Benjie 설명에 따라 ).

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file

보시다시피, sed그렇지 않으면 간단한 문제에 사용하는 것이 문제가됩니다. 보다 간단하고 적절한 해결책은 이 답변을 참조하십시오 .


45
@Arjan and Masi : OS X는 sedGNU 대신 BSD를 사용 sed하므로 둘 사이에 약간의 미묘한 차이가있을 수 있습니다. OS X 및 * nix 시스템 모두에서 작업하는 경우 지속적인 고통입니다. 나는 보통 GNU coreutilsfindutilsOS X에 설치 하고 BSD 버전을 무시합니다.
Telemachus

50
:a이 지점 라벨의, 레지스터 아니다. b"goto"처럼 작동 하는 명령 * 의 대상입니다 . 이를 레지스터라고하면 저장 위치를 ​​만들 수 있음을 의미합니다. 두 개의 "레지스터"만 있습니다. 하나는 스크립트에서 사용하지 않는 "홀드 스페이스"라고하며 다른 하나는 "패턴 스페이스"라고합니다. 이 N명령은 줄 바꿈과 입력 파일의 다음 줄을 패턴 공간에 추가합니다. [* 여러 레이블과 b명령을 가질 수 있습니다 . b레이블 char이 추가되지 않은 명령 이 있으면 스크립트의 끝으로 분기되어 다음 줄을 읽고 다시 반복합니다.]
추가 통지가있을 때까지 일시 중지되었습니다.

108
세미콜론으로 분리하지 않고 명령을 별도로 실행하여이 크로스 플랫폼 (예 : Mac OS X)을 실행할 수 있습니다. sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'
Benjie

74
왜 이것이 엉뚱한 혼란에 대해 언급하지 않습니까? (답변 자체가 아니라 제안 된 답변이 매우 간단한 문제에 대한 최상의 해결책 인 프로그램). Sed는 보통 잘 돌아가는 차처럼 보이지만 근처의 특정 거리로 운전하려면 헬리콥터로 차를 들어 올리는 것이 유일한 방법입니다.
Ark-kun

12
사람들에게 어서-작동하지 않는 미친, 이해할 수없는 솔루션에 대한 261 upvotes ???? sed는 한 줄로 간단한 대체를위한 훌륭한 도구입니다. 슬픔 ....
Ed Morton

1711

sed라인 기반 입력에 사용됩니다. 필요한 것을 할 수 있지만.


여기서 더 좋은 옵션은 tr다음과 같이 명령 을 사용하는 것입니다.

tr '\n' ' ' < input_filename

또는 개행 문자를 완전히 제거하십시오.

tr -d '\n' < input.txt > output.txt

또는 긴 버전의 GNU 버전이있는 경우

tr --delete '\n' < input.txt > output.txt

88
Sed는 줄 기반이므로 개행을 이해하기가 어렵습니다.
Alexander Gladysh

191
sed는 입력의 "스트림"에서 작동하지만 개행으로 구분 된 청크로 이해합니다. 그것은 유닉스 도구이므로 한 가지 일을 아주 잘합니다. 한 가지는 "파일 단위로 작업"입니다. 다른 작업을 수행하는 것은 어렵고 버그가 발생할 위험이 있습니다. 이야기의 교훈은 올바른 도구를 선택하는 것입니다. 귀하의 질문 중 상당수는 "이 도구가 결코 의도하지 않은 작업을 수행하도록하려면 어떻게해야합니까?" 그 질문들은 흥미롭지 만, 실제 문제를 해결하는 과정에서 제기된다면 아마도 잘못하고있는 것일 것입니다.
dmckee ---

7
@JBBrown tr은 파이프 라인 구축에 종종 간과되는 보석입니다.
dmckee --- 전 운영자 고양이

70
tr은 훌륭하지만 개행을 단일 문자로만 바꿀 수 있습니다. 줄 바꾸기를 문자열로 바꾸려면 다른 도구를 사용해야합니다
Eddy

21
@Eddy-tr을 사용하여 새 줄을 텍스트에 나타나지 않는 문자로 바꿨습니다 (백틱을 사용했습니다). sed를 사용하여 원하는 문자열로 백틱을 바꾸십시오
rjohnston

494

빠른 답변

sed ':a;N;$!ba;s/\n/ /g' file
  1. : a 라벨 'a'를 만듭니다.
  2. N 다음 줄을 패턴 공간에 추가
  3. $! 하지의 마지막 줄 경우 , 분기 라벨 'A'(에 이동)
  4. 대체 , / \ n / 새로운 라인에 대한 정규식 , / / 공백으로 , / g 글로벌 경기 (여러 번 그것을 할 수있는)

sed는 마지막 줄에 도달 할 때까지 1 단계에서 3 단계까지 반복하여 모든 줄이 패턴 공간에 맞도록합니다. 여기서 sed는 모든 \ n 문자를 대체합니다.


대안

sed 와 달리 모든 대안 은 프로세스를 시작하기 위해 마지막 줄에 도달 할 필요가 없습니다.

bash 와 함께 , 느리게

while read line; do printf "%s" "$line "; done < file

, 나오지도 -like 속도를

perl -p -e 's/\n/ /' file

TR ,보다 빠르게 나오지도 하나 개의 문자로 대체 할 수 있습니다 만

tr '\n' ' ' < file

붙여 넣기 , 그럴 -like 속도, 하나 개의 문자로 대체 할 수 있습니다 만

paste -s -d ' ' file

AWK , 그럴 -like 속도

awk 1 ORS=' ' file

"echo $ (<file)" 와 같은 다른 대안 은 느리고 작은 파일에서만 작동하며 전체 파일을 처리하여 프로세스를 시작해야합니다.


sed FAQ 5.10 의 긴 답변

5.10. \ n 이스케이프
시퀀스를 사용하여 줄 바꿈을 일치 시키거나 삭제할 수없는 이유는 무엇 입니까? \ n을 사용하여 두 줄 이상을 일치시킬 수없는 이유는 무엇입니까?


줄이
패턴 공간에 배치되기 전에 줄 바꾸기가 항상 제거 되므로 \ n은 줄 끝에서 줄 바꿈과 일치하지 않습니다 . 패턴 공간에 2 개 이상의 라인을 가져 오려면
'N'명령 또는 이와 유사한 것을 사용 하십시오 (예 : 'H; ...; g;').

Sed는 다음과 같이 작동합니다 .sed는 한 번에 한 줄을 읽고
종료하는 줄 바꿈을 잘라 내고
, sed 스크립트가 처리하거나 변경할 수 있는 패턴 공간에 남은 것을 넣고 패턴 공간
이 인쇄되면 stdout에 줄 바꿈을 추가합니다 (또는 파일). 경우]
패턴 영역이 완전히 또는 부분적으로 'D'또는 'D'로 삭제되면,
줄 바꿈이되어 있지 이러한 경우에 추가. 따라서 스크립트는

  sed 's/\n//' file       # to delete newlines from each line             
  sed 's/\n/foo\n/' file  # to add a word to the end of each line         

줄이 패턴 공간에 들어가기 전에 후행 줄 바꿈이 제거되므로 작동하지 않습니다
. 위 작업을 수행하려면
대신 다음 스크립트 중 하나를 사용하십시오.

  tr -d '\n' < file              # use tr to delete newlines              
  sed ':a;N;$!ba;s/\n//g' file   # GNU sed to delete newlines             
  sed 's/$/ foo/' file           # add "foo" to end of each line          

GNU sed 이외의 sed 버전은
패턴 버퍼 의 크기에 제한이 있으므로 Unix 'tr'유틸리티가 선호됩니다.
파일의 마지막 줄에 줄 바꿈이 포함되어 있으면 GNU sed는
해당 줄 바꿈을 출력에 추가 하지만 다른 줄은
모두 삭제 하지만 tr은 줄 바꾸기를 모두 삭제합니다.

둘 이상의 라인 블록을 일치시키기 위해 3 가지 기본 선택이 있습니다.
(1) 'N'명령을 사용하여 다음 라인을 패턴 공간에 추가하십시오.
(2) 'H'명령을 두 번 이상 사용하여 현재 행
을 보류 공간 에 추가 한 다음
x, g 또는 G 를 사용하여 보류 공간에서 행을 검색하십시오 . 또는 (3) 주소 범위를 사용하여 (
두 섹션 3.3 참조) 지정된 두 주소 사이의 라인을 일치시킵니다.

선택 (1)과 (2)는 \ n을 패턴 공간에 넣고
원하는대로 처리 할 수 있습니다 ( 's / ABC \ nXYZ / alphabet / g').
'N'을 사용하여 행 블록을 삭제하는 한 가지 예 는 4.13 절
( " 특정 연속 행 블록을 어떻게 삭제 합니까?")에 나타납니다. 이
예제는 delete 명령을
'p'(인쇄), 'i'(삽입), 'c'(변경), 'a'(추가)
또는 's'(대체) 와 같은 다른 것으로 변경하여 수정할 수 있습니다. .

선택 (3)는 \ N 패턴 영역에 투입하지 않을 것이다, 그러나 않습니다
당신이하지 않아도 될 수 있도록, 연속 선 블록을 일치
에도 필요한 \ n 당신이 찾고있는 것을 발견합니다. GNU sed
버전 3.02.80 부터 다음 구문을 지원합니다.

  sed '/start/,+4d'  # to delete "start" plus the next 4 lines,           

기존의 '/ here /, / to there / {...}'범위
주소 외에도 \ n을 완전히 사용하지 않는 것이 가능할 수 있습니다.


6
tr좋은 아이디어였으며 귀하의 전반적인 범위는 최고 품질의 답변을 제공합니다.
새로운 Alexandria

1
( 표준 유틸리티 ) paste... 및 기타 모든 것을 사용하기 위해 +1 !
Totor


4
이 답변의 가장 중요한 부분은 "긴 답변"은 명령의 작동 방식과 이유를 정확하게 설명한다는 것입니다.
pdwalker

3
이것은 stackexchange에서 읽은 수천 가지 답변 중 가장 도움이 될 수 있습니다. 여러 줄에서 여러 문자를 일치시켜야합니다. 여러 줄로 된 이전 sed 예제는 없으며 tr은 여러 문자 일치를 처리 할 수 ​​없습니다. Perl은 좋아 보이지만 예상대로 작동하지 않습니다. 가능한 경우이 답변에 여러 번 투표했습니다.
mightypile 2016 년

225

더 짧은 awk 대안 :

awk 1 ORS=' '

설명

awk 프로그램은 조건부 코드 블록으로 구성된 규칙으로 구성됩니다.

condition { code-block }

코드 블록을 생략하면 기본값이 사용됩니다 { print $0 }. 따라서 1는 실제 조건으로 해석되어 print $0각 라인마다 실행됩니다.

경우 awk의 값에 기초하여 레코드로 그것을 분할 입력 판독 RS기본적 개행이다 (기록 분리기), 따라서 awk것이다 입력 파싱 기본적으로 선 현명한. 분할에는 RS입력 레코드에서 제거하는 작업도 포함됩니다 .

이제 레코드를 인쇄 할 때 ORS(Output Record Separator)가 추가되고 기본값은 다시 줄 바꿈입니다. 따라서 ORS공백으로 변경하면 모든 줄 바꿈이 공백으로 변경됩니다.


5
나는 다른 것보다 훨씬 더 읽기 쉬운이 간단한 솔루션을 좋아합니다
Fedir RYKHTIK

8
더 의미가 있다면, 이것은 효과적으로 다음과 같이 쓰여질 수 있습니다 : awk 'BEGIN { ORS=" " } { print $0 } END { print "\n"} ' file.txt(시작 / 끝을 설명하기 위해 끝 줄 바꿈 추가); "1"은 true(라인 처리) 및 print(라인 인쇄 )로 평가됩니다 . 예를 들어, 패턴과 일치하는 행에서만 작업하는 조건부도이 표현식에 추가 될 수 있습니다. awk 'BEGIN { ORS=" " } /pattern/ { print $0 } END { print "\n"} '
michael

2
당신은 더 simle 수행 할 수 있습니다 codeAWK 'ORS를 = ""'file.txt를code
우디

이처럼 awk를 사용하면 불행히도 파일의 마지막 줄 바꿈도 삭제됩니다. `cat file | echo $ (tr "\ 012" "")`트릭을 수행합니다. 맵시 있는.
Bernie Reiter

143

gnu sed에는 -z널로 구분 된 레코드 (행)에 대한 옵션 이 있습니다. 당신은 전화를 할 수 있습니다 :

sed -z 's/\n/ /g'

4
입력에 널이 포함되어 있어도 레코드 분리 문자로 유지됩니다.
Toby Speight

6
null이 없으면 전체 입력을로드하지 않습니까? 이 경우 멀티 기가 바이트 파일 처리가 충돌 할 수 있습니다.
Ruslan

3
@Ruslan, 예, 전체 입력을로드합니다. 이 솔루션은 멀티 기가 바이트 파일에는 적합하지 않습니다.
JJoao

7
이것이 가장 좋은 대답입니다. 다른 표현들은 기억하기에 너무 왜곡되었습니다. @JJoao와 함께 사용할 수 있습니다 -u, --unbuffered. man마법사 상태는 "입력 파일로부터 데이터의 최소량을로드하고 수시로 출력 버퍼를 플러시".
not2qubit

그래서. 많은. 이.
sjas

85

버전은 예상되는 방식으로 작동합니다.

perl -i -p -e 's/\n//' file

의견에서 지적했듯이, 이것이 편집되었음을 주목할 가치가 있습니다. 정규 표현식 이 생각보다 똑똑하지 않은 -i.bak경우 교체하기 전에 원본 파일의 백업을 제공합니다 .


23
-i접미사 없이는 백업하지 않는다는 것을 적어도 언급하십시오 . -i.bak쉽고 못생긴 실수 (예 : -p파일 을 입력 하지 않고 파일을 지우는 것을 잊음)로부터 보호합니다 .
Telemachus

6
@ Telemachus : 그것은 공평한 점이지만 어느 쪽이든 논쟁 할 수 있습니다. 내가 언급하지 않은 주된 이유는 OP의 질문에있는 sed 예제가 백업을하지 않기 때문에 여기에서는 불필요한 것 같습니다. 다른 이유는 실제로 백업 기능을 사용한 적이 없기 때문입니다 (실제로 자동 백업이 성가시다는 것을 알았습니다). 세 번째 이유는 명령 행을 4 자로 길게 만드는 것입니다. 더 나쁘게 (아마도 더 나쁘게), 나는 강박적인 미니멀리스트입니다. 나는 단지 간결함을 선호합니다. 나는 당신이 동의하지 않는다는 것을 알고 있습니다. 앞으로 백업에 대해 경고하도록 최선을 다할 것입니다.
ire_and_curses

6
@ Ire_and_curses : 사실, 당신은 나를 무시하는 것에 대해 좋은 주장을했습니다. 즉, 당신은 당신이 당신의 선택에 대한 이유가 있고, 내가 선택에 동의하는지 아닌지, 나는 확실히 그것을 존중합니다. 나는 왜 완전히 확실하지 않지만, 최근 에이 특정 문제 ( -i접미사가없는 Perl 의 깃발)에 대해 눈물을 흘 렸습니다 . 나는 곧 다른 것에 집착 할 다른 것을 찾을 것이라고 확신한다. :)
Telemachus

-파일 이름 을 지정하여 stdin에서 작동하지 않는 것은 실제로 불행한 일입니다 . 그렇게 할 방법이 있습니까? 파일 수정에 대해 걱정하지 않아도되는 방법은 cat로 시작하는 파이프 라인을 사용하는 것입니다.
Steven Lu

@StevenLu Perl은 파일 이름이 제공되지 않으면 기본적으로 STDIN에서 읽습니다. 그래서 당신은 할 수 있습니다perl -i -p -e 's/\n//' < infile > outfile
ire_and_curses

44

누가 필요 sed합니까? bash방법 은 다음과 같습니다 .

cat test.txt |  while read line; do echo -n "$line "; done

2
공감, 나는 일반적으로 최고 답변을 사용했지만 / dev / urandom을 통해 파이핑 할 때 sed는 EOF까지 인쇄되지 않으며 ^ C는 EOF가 아닙니다. 이 솔루션은 줄 바꿈이 나타날 때마다 인쇄됩니다. 정확히 내가 필요한 것! 감사!
Vasiliy Sharapov

1
echo -n`cat days.txt` 이 게시물에서
Tony

9
@Tony 역 따옴표가 사용되지 않으며 고양이가 중복 ;-)를 사용하는 이유는 $ (<이 days.txt) 에코
seumasmac

10
를 사용하지 않아도 cat: while read line; do echo -n "$line "; done < test.txt. 하위 쉘이 문제인 경우 유용 할 수 있습니다.
Carlo Cannas

5
echo $(<file)줄 바꿈뿐만 아니라 모든 공백을 단일 공간으로 압축 합니다 . 이는 OP가 요구하는 것 이상입니다.
glenn jackman

27

전체 파일을 메모리로 읽지 않고 awk를 사용하여 모든 줄 바꿈을 공백으로 바꾸려면 다음을 수행하십시오.

awk '{printf "%s ", $0}' inputfile

최종 개행을 원할 경우 :

awk '{printf "%s ", $0} END {printf "\n"}' inputfile

공백 이외의 문자를 사용할 수 있습니다.

awk '{printf "%s|", $0} END {printf "\n"}' inputfile

END{ print ""}후행 줄 바꿈에 대한 짧은 대안입니다.
Isaac

22
tr '\n' ' ' 

명령입니다.

간단하고 사용하기 쉽습니다.


14
또는 단순히 tr -d '\n'공백을 추가하지 않으려 는 경우
spuder

21

세개.

  1. tr(또는 cat등)는 절대 필요하지 않습니다. (GNU) sed및 (GNU) awk는 결합하면 필요한 모든 텍스트 처리의 99.9 %를 수행 할 수 있습니다.

  2. 스트림! = 라인 기반. ed라인 기반 편집기입니다. sed아니다. 차이점에 대한 자세한 내용 은 sed 강의 를 참조하십시오 . 대부분의 사람들 sed은 기본적으로 SIMPLE 일치에 대한 패턴 일치가별로 욕심이 없기 때문에 라인 기반으로 혼동 합니다. (글로벌 명령으로 달리 지정되지 않은 한)를 찾습니다. 한 번에 한 줄만 평가하므로 STREAM 기반이 아닌 라인 기반의 경우 전역 명령도 없습니다. 달리기를 시도하십시오 ed; 차이점을 알 수 있습니다. edfor 루프에서와 같이 특정 줄을 반복하고 싶을 때 매우 유용하지만 대부분의 경우 원할 것 sed입니다.

  3. 그 말은

    sed -e '{:q;N;s/\n/ /g;t q}' file
    

    GNU sed버전 4.2.1 에서 잘 작동합니다 . 위의 명령은 모든 줄 바꿈을 공백으로 바꿉니다. 입력하기에는 추악하고 약간 성가 시지만 잘 작동합니다. 의 {}경우는 위생 상 이유로 만 포함되므로 제외 할 수 있습니다.


3
sed기본적인 일만 할만큼만 알고있는 사람으로서, 당신이 할 수있는 일이 sed아니라 진행 상황을 이해하는 것이 얼마나 쉬운 지에 대해 말해야합니다 . 나는 일하기가 매우 어려워서 sed사용할 수있을 때 더 간단한 명령을 선호합니다.
Nate

t q조건부 점프로 사용 s/\n / /하면 전체 파일을 메모리로 읽지 않고 (공백으로 시작하는 모든 줄을 결합하는 것과 같은) 패턴으로 작동 합니다. 멀티 메가 바이트 파일을 변환 할 때 편리합니다.
textshell

당신이 연결 한 기사는 당신이 말하는 것을 반영하지 않습니다
hek2mgl

이는 큰 입력에서 허용되는 답변보다 거의 800 배 느립니다. 이것은 점점 더 큰 입력에서 모든 라인을 대체하기 때문입니다.
Thor

13

: a 레이블이있는 대답 ...

sed를 사용하여 줄 바꿈 (\ n)을 바꾸려면 어떻게해야합니까?

... 명령 줄의 freebsd 7.2에서 작동하지 않습니다 :

(echo foo; 에코 바) | sed ': a; N; $! ba; s / \ n / / g'
sed : 1 : ": a; N; $! ba; s / \ n / / g": 미사용 라벨 'a; N; $! ba; s / \ n / / g'
푸
바

그러나 sed 스크립트를 파일에 넣거나 -e를 사용하여 sed 스크립트를 "빌드"하면 ...

> (에코 foo; 에코 바) | sed -e : a -e N -e '$! ba'-e 's / \ n / / g'
푸 바

또는 ...

> cat > x.sed << eof
:a
N
$!ba
s/\n/ /g
eof

> (echo foo; echo bar) | sed -f x.sed
foo bar

아마도 OS X의 sed가 비슷할 것입니다.


일련의 -e 인수는 MKS를 사용하는 Windows에서 나를 위해 일했습니다! 감사!
JamesG

12

이해하기 쉬운 솔루션

나는이 문제가 있었다. 키커 내가 BSD의 (맥 OS X)와 GNU의 (리눅스와의 작업에 대한 해결책이 필요하다고했다 Cygwin에서 ) sedtr:

$ echo 'foo
bar
baz


foo2
bar2
baz2' \
| tr '\n' '\000' \
| sed 's:\x00\x00.*:\n:g' \
| tr '\000' '\n'

산출:

foo
bar
baz

(후행 줄 바꿈이 있음)

그것은 리눅스, OS X, 그리고 BSD에서 작동 도하지 않고 - UTF-8 지원 또는 엉터리 단자.

  1. tr개행을 다른 문자로 바꾸는 데 사용 합니다.

    NULL( \000또는 \x00)는 UTF-8 지원이 필요하지 않으며 사용되지 않기 때문에 좋습니다.

  2. 사용 sed에 맞게NULL

  3. tr필요한 경우 추가 줄 바꿈을 다시 바꾸는 데 사용하십시오.


1
명명법에 대한 미묘한 참고 사항 : 문자 \000는 일반적으로 NUL(하나의 L) 이라고하며 NULL일반적으로 제로 포인터 (C / C ++)에 대해 이야기 할 때 사용됩니다 .
sqweek


9

나는 전문가가 아니지만 sed먼저 " N"를 사용하여 패턴 공간에 다음 줄을 추가해야 할 것 같습니다 . 책 sed & awk 의 "Advanced sed Commands"에서 "Multiline Pattern Space"섹션 (Dale Dougherty and Arnold Robbins; O'Reilly 1997; preview의 107 페이지 ) :

multiline Next (N) 명령은 새로운 입력 줄을 읽고이를 패턴 공간의 내용에 추가하여 여러 줄 패턴 공간을 만듭니다. 패턴 공간의 원래 내용과 새 입력 줄은 줄 바꿈으로 구분됩니다. 포함 된 개행 문자는 이스케이프 시퀀스 "\ n"에 의해 패턴에서 일치시킬 수 있습니다. 여러 줄 패턴 공간에서 메타 문자 "^"는 포함 된 줄 바꿈 뒤의 문자가 아니라 패턴 공간의 첫 문자와 일치합니다. 마찬가지로 "$"는 포함 된 개행 문자가 아니라 패턴 공간의 마지막 개행 문자와 만 일치합니다. 다음 명령이 실행 된 후 스크립트의 후속 명령으로 제어가 전달됩니다.

보낸 사람 man sed:

[2addr] N

추가 된 자료를 원본 내용과 분리하기 위해 포함 된 개행 문자를 사용하여 다음 입력 행을 패턴 공간에 추가하십시오. 현재 줄 번호가 변경됩니다.

나는 한 이 사용 검색 문자열가 "고아"다음 행에서 발견 될 수있는 잘못된 형식의 로그 파일 (복수)를 검색 할 수 있습니다.


7

tr을 사용하여 줄 바꿈을 탭으로 바꾼 다음 탭을 원하는대로 바꿈으로써 하이브리드 방식을 사용했습니다. 이 경우
HTML 나누기를 생성하려고하므로 " "입니다.

echo -e "a\nb\nc\n" |tr '\n' '\t' | sed 's/\t/ <br> /g'`

6

위의 "tr"솔루션에 대한 응답으로 Windows (아마 Gnuwin32 버전 tr 사용)에서 제안 된 솔루션은 다음과 같습니다.

tr '\n' ' ' < input

나를 위해 작동하지 않으면 오류가 발생하거나 실제로 어떤 이유로 \ nw / ''를 대체합니다.

tr의 다른 기능을 사용하여 "delete"옵션 -d가 작동했습니다.

tr -d '\n' < input

또는 '\ n'대신 '\ r \ n'


3
Windows에서는 아마도을 사용해야 tr "\n" " " < input합니다. Windows 셸 (cmd.exe)은 아포스트로피를 인용 문자로 취급하지 않습니다.
키이스 톰슨

아니요, Windows 10 Ubuntu 하위 시스템에서는 다음을 사용해야합니다.tr "\n\r" " " < input.txt > output.txt
user1491819

이것은 Gnuwin32를 사용하는 Windows 10에서 작동합니다 cat SourceFile.txt | tr --delete '\r\n' > OutputFile.txt. 또는 Gnuwin32 대신 Gow (Windows의 Gnu), github.com/bmatzelle/gow/wiki
Alchemistmatt

5

방탄 솔루션. 이진 데이터 안전 및 POSIX 호환이지만 느립니다.

POSIX sedPOSIX 텍스트 파일POSIX 줄 정의 에 따라 입력이 필요 하므로 NULL 바이트와 너무 긴 줄은 허용되지 않으며 각 줄은 줄 바꿈 (마지막 줄 포함)으로 끝나야합니다. 따라서 임의의 입력 데이터를 처리하기 위해 sed를 사용하기가 어렵습니다.

다음 솔루션은 sed를 피하고 대신 입력 바이트를 8 진 코드로 변환 한 다음 다시 바이트로 변환하지만 8 진 코드 012 (줄 바꾸기)를 가로 채서 대체 문자열을 대신 출력합니다. 내가 알 수있는 한 솔루션은 POSIX 호환이므로 다양한 플랫폼에서 작동해야합니다.

od -A n -t o1 -v | tr ' \t' '\n\n' | grep . |
  while read x; do [ "0$x" -eq 012 ] && printf '<br>\n' || printf "\\$x"; done

POSIX 참조 문서 : sh , shell command language , od , tr , grep , read , [ , printf .

read, [그리고 printf적어도 bash는 내장 기능이 있지만, 그 아마 그래서 일부 플랫폼은 각 입력 바이트가 일을 느리게 할 하나 개 이상의 새로운 프로세스를 시작합니다 일 수 있었다, POSIX에 의해 보장되지 않습니다. bash 에서도이 솔루션은 약 50kB / s에 도달하므로 큰 파일에는 적합하지 않습니다.

Ubuntu (bash, dash 및 busybox), FreeBSD 및 OpenBSD에서 테스트되었습니다.


5

경우에 따라 RS다른 문자열이나 문자로 변경할 수 있습니다 . 이런 식으로 \ n은 sub / gsub에 사용할 수 있습니다 :

$ gawk 'BEGIN {RS="dn" } {gsub("\n"," ") ;print $0 }' file

쉘 스크립팅의 힘은 한 가지 방법으로 그것을하는 방법을 모른다면 다른 방법으로 할 수 있다는 것입니다. 그리고 간단한 문제에 대한 복잡한 해결책을 만드는 것보다 고려해야 할 것이 더 많습니다.

gawk가 느리고 ... 파일을 메모리로 읽는 것에 관해서는, 나는 이것을 모른다. 그러나 나에게 gawk는 한 줄에서 작동하는 것처럼 보이고 매우 빠르다 (다른 것들만큼 빠르지 않다) 작성하고 테스트하는 시간도 중요합니다).

MB 및 GB의 데이터를 처리하며 찾은 유일한 제한은 줄 크기입니다.


5

불행히도 Windows 줄 끝을 처리해야 할 경우 및를 제거해야 \r합니다.\n

tr '[\r\n]' ' ' < $input > $output

이것은 대체 [공백과 \r공백 및 \n공백과 ]공백으로. 또는 문자를 tr -d '\r\n' <file제거 하지만 요청되는 내용도 아닙니다. 는 ( 가까운 지 여부에 관계없이) 문자 가 제거 되어 OP에 필요할뿐만 아니라 OP에 필요한 것보다 더 가깝습니다 (여전히이 백 슬래시 표기법을 이해 한다고 가정 ). \r\ntr -d '\r' <file\r\ntr
tripleee

4

당신은 사용할 수 있습니다 xargs- 그것은 대체합니다 \n기본적으로 공간.

그러나 입력에의 경우가 있다면 unterminated quote(예 : 주어진 줄의 인용 부호가 일치하지 않는 경우) 문제가 발생합니다 .


xargs는 또한 마지막 줄을 잘 처리합니다.
AAAfarmclub

4

허용 \ n을 사용하여 찾기 및 바꾸기

sed -ie -z 's/Marker\n/# Marker Comment\nMarker\n/g' myfile.txt

채점자

된다

# 마커 코멘트

채점자


4

왜 간단한 해결책을 찾지 못했 awk습니까?

awk '{printf $0}' file

printf 원래 줄을 공백이나 다른 줄로 구분하려면 줄 바꿈없이 모든 줄을 인쇄합니다.

awk '{printf $0 " "}' file

echo "1\n2\n3" | awk '{printf $0}', 이것은 나를 위해 작동합니다. @ edi9999
Itachi

죄송합니다, fprintf
edi9999

이 창에 대한 자식의 bash에서 나를 위해 일하는 유일한 방법이었다
플라톤

3

Mac OS X (FreeBSD sed 사용) :

# replace each newline with a space
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g; ta'
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g' -e ta


3

Awk 사용 :

awk "BEGIN { o=\"\" }  { o=o \" \" \$0 }  END { print o; }"

2
외부 따옴표를 작은 따옴표로 변경하면 따옴표와 달러 기호를 이스케이프 처리하지 않아도됩니다. 문자 "o"는 일반적으로 숫자 "0"과 혼동 될 수 있으므로 변수 이름으로 잘못된 선택으로 간주됩니다. 또한 변수를 초기화 할 필요가 없으며 기본값은 null 문자열입니다. 그러나 불필요한 선행 공간을 원하지 않는 경우 : awk '{s = s sp $0; sp = " "} END {print s}'. 그러나 전체 파일을 메모리로 읽지 않고 awk를 사용하는 방법은 내 대답을 참조하십시오.
추후 공지가있을 때까지 일시 중지되었습니다.

제발 확인 토르의 답변을 대신. 이 방법이 더 효율적 읽고 그냥 더 나은 비해이 방법 (이 경우에도 모든 수단에 의한 일)!
mschilli

야, 알겠다 내 얼굴에 그것을 문지르지 않아도됩니다 :-) Thor의 대답은 어쨌든 페이지의 위입니다 (그렇습니다).
kralyk

3

내가 특히 좋아하는 해결책은 모든 파일을 보류 공간에 추가하고 파일 끝에서 모든 줄 바꿈을 바꾸는 것입니다.

$ (echo foo; echo bar) | sed -n 'H;${x;s/\n//g;p;}'
foobar

그러나 누군가는 일부 sed 구현에서 홀드 공간이 유한 할 수 있다고 말했습니다.


1
답변에 빈 문자열로 대체하면 항상 H를 사용하여 보류 공간에 추가한다는 의미는 보류 공간이 줄 바꿈으로 시작한다는 것을 의미합니다. 이를 피하려면 다음을 사용해야합니다.1h;2,$H;${x;s/\n/x/g;p}
Jeff

3

줄 바꿈을 문자열로 바꾸고 마지막 줄 바꿈도 바꾸십시오.

순수한 tr솔루션은 단일 문자로만 대체 할 수 있으며 순수한 sed솔루션은 입력의 마지막 개행을 대체하지 않습니다. 다음 솔루션은 이러한 문제를 해결하고 UTF-8 로캘을 사용하더라도 이진 데이터에 대해 안전한 것으로 보입니다.

printf '1\n2\n3\n' |
  sed 's/%/%p/g;s/@/%a/g' | tr '\n' @ | sed 's/@/<br>/g;s/%a/@/g;s/%p/%/g'

결과:

1<br>2<br>3<br>


@StevenLu : 아니오, @입력이 정상입니다. %a다시 이스케이프 처리 됩니다. 솔루션은 POSIX와 완전히 호환되지 않을 수 있습니다 (NULL 바이트는 허용되지 않으므로 이진 데이터에는 적합하지 않으며 모든 줄은 줄 바꿈으로 끝나야 tr출력이 실제로 유효하지 않습니다).
Håkon A. Hjortland

아 나는 당신이 그것을 고쳤다 참조하십시오. Kinda는 간단한 작업이지만 좋은 작업이 무엇인지 혼란스러워했습니다.
Steven Lu

3

"정상"대체 후 개행 을 도입하는 것은 sed 입니다. 먼저 줄 바꿈 문자를 자르고 지시에 따라 처리 한 다음 줄 바꿈을 도입합니다.

sed 를 사용하면 줄을 바른 후 줄의 "끝"(개행 문자가 아님)을 각 입력 줄에 대해 원하는 문자열로 바꿀 수 있습니다. 그러나 sed 는 다른 라인을 출력합니다. 예를 들어, "end of line"을 "==="(단일 공백으로 바꾸는 것보다 일반적으로)으로 바꾸려고한다고 가정합니다.

PROMPT~$ cat <<EOF |sed 's/$/===/g'
first line
second line
3rd line
EOF

first line===
second line===
3rd line===
PROMPT~$

줄 바꿈 문자를 문자열 로 바꾸려면 이전에 지적한 것처럼 비효율적으로 tr을 사용 하여 줄 바꿈 문자를 "특수 문자"로 바꾼 다음 sed 를 사용 하여 해당 문자를 원하는 문자열로 바꿉니다. .

예를 들면 다음과 같습니다.

PROMPT~$ cat <<EOF | tr '\n' $'\x01'|sed -e 's/\x01/===/g'
first line
second line
3rd line
EOF

first line===second line===3rd line===PROMPT~$

3

이 방법을 사용할 수도 있습니다

sed 'x;G;1!h;s/\n/ /g;$!d'

설명

x   - which is used to exchange the data from both space (pattern and hold).
G   - which is used to append the data from hold space to pattern space.
h   - which is used to copy the pattern space to hold space.
1!h - During first line won't copy pattern space to hold space due to \n is
      available in pattern space.
$!d - Clear the pattern space every time before getting next line until the
      last line.

흐름 :
입력에서 첫 번째 줄을 가져 오면 교환이 이루어 지므로 1은 보류 공간으로 이동하고 \ n은 패턴 공간으로 이동 한 다음 보류 공간을 패턴 공간에 추가 한 다음 대체가 수행되고 패턴 공간이 삭제됩니다.
두 번째 라인 교환이 수행되는 동안 2는 홀드 스페이스로 이동하고 1은 패턴 스페이스로 이동 한 다음 G홀드 스페이스를 패턴 스페이스에 추가 한 다음 h패턴을 복사하여 대체하고 삭제합니다. 이 작업은 eof에 도달 할 때까지 계속되고 정확한 결과를 인쇄합니다.


그러나 echo 'Y' | sed 'x;G;1!h;s/\n/X/g;$!d'결과는 다음과 같습니다 XY.
Spooky

3

Zsolt Botykai 의 대답 과 거의 동일한 또 다른 GNU sed 방법 이지만, 자주 사용되지 않는 ( 음역 ) 명령을 사용하여 1 바이트 의 코드 를 저장 합니다 (후행 ).sedyg

sed ':a;N;$!ba;y/\n/ /'

GNU 보다 빠른 속도 (아마도 속도는 20 배 더 빠름) y보다 더 빨리 실행 되기를 희망 하지만 GNU sed v4.2.2 는 보다 약 4 % 느립니다 .str ys


보다 편리한 BSD sed 버전 :

sed -e ':a' -e 'N;$!ba' -e 'y/\n/ /'

2
BSD sed y는 약 15 % 빠릅니다. 실제 예제는 이 답변 을 참조하십시오 .
Thor

또한 BSD sed 명령을 사용하면 레이블 다음에 종료해야하므로 sed -e ':a' -e 'N;$!ba' -e 'y/\n/ /'갈 길입니다.
ghoti
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.