sed가 줄 바꾸기 문자를 대체 할 수 있습니까?


42

sed 및 new line character에 문제가 있습니까?
다음 내용의 test.txt 파일이 있습니다.

aaaaa  
bbbbb  
ccccc  
ddddd  

다음은 작동하지 않습니다.
sed -r -i 's/\n/,/g' test.txt

나는 tr이것을 사용할 수 있지만 내 질문은 sed로는 불가능한 것 같습니다.

이것이 파일을 한 줄씩 처리하는 부작용이라면 이것이 왜 발생하는지에 관심이 있습니다. 나는 grep새로운 줄을 제거 한다고 생각 합니다. sed도 마찬가지입니까?


1
이 경우 sed가 사용하기 가장 좋은 도구가 아닐 수 있습니다 (예 : "tr"). 보다 직관적이고, 읽기 / 유지하기 쉽고, 더 나은 성능 (특히 빅 데이터) 등의 도구가 있습니다. ... 망치를 사용하여 나사를 넣지 마십시오 (작동하더라도). : 당신은 비교에서 찾을 수 있습니다 http://slash4.de/blog/python/sed-replace-newline-or-python-awk-tr-perl-xargs.html
omoser

2
tr후행을 추가하고 ,종료되지 않은 행을 출력합니다. paste대신 사용하는 것이 가장 좋습니다 :paste -sd , test.txt
Stéphane Chazelas

답변:


48

GNU sed에서 제공하고 제공 POSIXLY_CORRECT되지 않은 환경 (단일 라인 입력) :

sed -i ':a;N;$!ba;s/\n/,/g' test.txt

에서 https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n :

  1. 통해 라벨을 만들 :a
  2. 패턴 공간에 현재와 다음 줄을 추가하십시오. N
  3. 우리가 마지막 줄에 이전하는 경우, 생성 된 레이블 분기 $!ba( $!마지막으로 줄 바꿈이 있어야 수단이 마지막 줄에 작업을 수행하는하지 (로)).
  4. 마지막으로 대체는 모든 줄 바꿈을 패턴 공간 (전체 파일)에서 쉼표로 바꿉니다.

이 것이 나오지하는 문제는이 issue.It 왜 그냥 라인을 읽고, 함께 새로운 라인 문자 (또는 마지막 문자를) 대체 할 수있는 이해할 수없는 line.But I에 의해 라인을 읽는 것을 나타내는 것

1
@jim 그것은 버퍼에 일치하지 않는 것처럼 보이지만 sed에 능숙하지 않습니다. 아마 다른 누군가가 그것에 대해 밝힐 수 있습니다. 특정 정보로 Q를 확장해야 사람들이 정보를 읽고 대답 할 가능성이 높아집니다.
Anthon

이러한 결과ba: Event not found
krb686

@ krb686 당신이 말하는 "This"는 무엇입니까? sed정확한 옵션으로 위 명령 을 실행 했습니까 ? 어떤 test.txt 파일에? 어떤 버전의 sed(시도 sed --version)?
Anthon

@Anthon 죄송합니다. "the"라고 말한 것 같습니다. 나는 csh가 나를 탈출해야한다고 알려주는 다른 SO 게시물을 읽었다 !. 흥미롭게도, 그것은 여전히 ​​나를 위해 작동하지 않았고 스크립트 !에서 두 번 탈출해야 했습니다 .csh. 그래서 지금은 실제로 문제가 없지만 왜 그런지 아십니까? 나를 위해 일한 것은sed :a;N;$\\!ba;s/\n/ /g'
krb686

16

이것은 GNU와 함께 작동합니다 sed:

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

-z 4.2.2부터 포함

NB. -z분리 문자를 널 문자 ( \0) 로 변경합니다 . 입력에 널 문자가 포함되지 않은 경우 전체 입력이 단일 행으로 처리됩니다. 이것에는 한계가 있습니다.

마지막 줄의 줄 바꿈을 바꾸지 않으려면 다시 바꿉니다.

sed -z 's/\n/,/g;s/,$/\n/'

(GNU sed구문은 다시 한 번 말하지만 전체가 GNU에만 해당되므로 중요하지 않습니다)


3
이것은 OP가 원하지 않을 수도있는 후행 줄 바꿈을 대체합니다 ... 결과를 mikeserv 솔루션 과 비교하십시오 .
don_crissti

7

오라클 웹 사이트에서 :

sed 유틸리티는 파일을 한 줄씩 순차적으로 메모리로 읽어들입니다. 그런 다음 회선에 지정된 모든 조치를 수행하고 회선을 메모리에 다시 배치하여 요청 된 변경 사항이있는 단말기로 덤프합니다. 모든 작업이이 한 줄에 수행 된 후 파일의 다음 줄을 읽고 파일이 끝날 때까지 프로세스를 반복합니다.

기본적으로 이것은 sed가 한 줄씩 읽고 있기 때문에 줄 바꿈 문자가 일치하지 않음을 의미합니다.

https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n 의 솔루션 은 다음과 같습니다.

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

또는 휴대용 버전 ( ;점프 마크 레이블 뒤에 연결 되지 않은 상태 )

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

작동 방식에 대한 설명은 해당 페이지에서 제공됩니다.


이 수정 된 형식을 사용하여 VPN 로그를 구문 분석하고 사용자에게 "인증 된"및 타임 스탬프 정보를 같은 줄에 넣었습니다. 건배!
user208145

구문은 GNU에만 해당되며 심지어 GNU에서도 sedPOSIXLY_CORRECT가 환경에 있고 입력에 한 줄만 있으면 출력이 없습니다.
Stéphane Chazelas

5

sed\n패턴 공간을 채우기 직전에 후행 줄 바꿈을 항상 제거한 다음 스크립트 결과를 작성하기 전에 줄 바꿈을 추가합니다. \newline은 다양한 방법으로 패턴 공간에서 가지게 될 수있다 - 그러나 편집의 결과하지 않을 경우. 이것은 중요합니다. 패턴 공간의 \n줄거리는 sed항상 변화를 반영하며 입력 스트림에서는 발생하지 않습니다. \newlines는 sed알 수없는 입력으로 믿을 수 있는 유일한 구분 기호 입니다.

모든 \newlines를 쉼표로 바꾸고 파일이 크지 않은 경우 다음을 수행 할 수 있습니다.

sed 'H;1h;$!d;x;y/\n/,/'

즉에 대한 모든 입력 라인에 추가 h하는 대신 덮어 쓰기하는 첫 번째를 제외하고 - 오래된 공간 h후속 - 오래된 공간 \newline 문자. 그런 다음 마지막 d줄이 아닌 모든 줄 $!을 출력에서 빼 냅니다. 마지막 줄에서 H이전과 패턴 공간이 x변경되고 모든 \newline 문자가 y///쉼표로 변환됩니다.

큰 파일의 경우 이러한 종류의 문제는 sed라인 경계의 버퍼 인 문제를 유발할 수 있으며, 이러한 종류의 동작으로 쉽게 오버플로 될 수 있습니다.


2

또는 약간 더 간단한 구문을 사용할 수 있습니다.

sed ':a;N;s/\n/,/g;ba'

... 순서 변경 순서 만.


3
그러나 s점점 더 큰 패턴 공간에서 각 입력 라인에 대한 명령을 실행합니다 .
Stéphane Chazelas

1

여기에 아주 좋은 sed 마술이 있습니다. 그리고 패턴 공간 오버플로에 대해 몇 가지 좋은 점이 제기되었습니다. sed 는 가장 간단한 방법이 아니더라도 매우 작고 강력하기 때문에 sed 를 사용하는 것을 좋아합니다 . 그러나 한계가 있으며 많은 양의 데이터의 경우 패턴 공간이 어마 어마해야합니다.

GNU는 이렇게 말합니다.

이식 가능한 sed 스크립트를 작성하려는 사용자의 경우, 일부 구현은 패턴 길이 및 보류 공간에 대한 행 길이를 4000 바이트 이하로 제한하는 것으로 알려져 있습니다. posix 표준은 적합한 sed 구현이 최소 8192 바이트 라인 길이를 지원하도록 지정합니다. GNU sed에는 줄 길이에 대한 제한이 없습니다. malloc () 더 많은 (가상) 메모리를 사용할 수있는 한 원하는만큼 줄을 공급하거나 구성 할 수 있습니다.
그러나 재귀는 하위 패턴과 무한 반복을 처리하는 데 사용됩니다. 이는 사용 가능한 스택 공간이 특정 패턴으로 처리 할 수있는 버퍼 크기를 제한 할 수 있음을 의미합니다.

추가 할 내용이 많지 않지만 sed에 대한 안내로 향하고 싶습니다 . 훌륭합니다. http://www.grymoire.com/Unix/Sed.html

그리고 여기 내 해결책이 있습니다 :

for i in $(cat test.txt); do echo -n $i','; done; echo '' >> somewhere

잘 작동합니다



-1

개행을로 바꾸고 싶다고 가정 해 봅시다 \n. 나는 그것을하고 싶었으므로 여기에 내가 한 일이 있습니다.

(echo foo; echo bar; echo baz) | sed -r '$!s/$/\\n/' | tr -d '\n' 
# Output: foo\nbar\nbaz

마지막 동작을 제외한 모든 행에 대해 append를 추가하십시오 \n. 그런 다음로 줄 바꿈을 삭제하십시오 tr.


-rsedBSD가 아닌 GNU에서만 사용할 수 있습니다 .
kenorb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.