sed는 sed '='명령으로 제공된 \ n 만 제거합니다.


7

다음을 사용하여 파일을 만들었습니다.

printf 'this is \n not is \n is is \n this biz' > file2

모든 \ n (newline)을 제거하려고하면 sed의 삽입 된 번호의 줄 바꿈 만 제거합니다.

sed  '=' file2 | sed 'N; s/\n/ /' 

출력은 다음과 같습니다

 1 this is 
 2  not is 
 3  is is 
 4  this biz

그리고 내가 기대 한 것이 아닙니다 :

1 this is  2  not is  3  is is  4  this biz

나는 길을 잃었다.

답변:


7

두 번째 sed스크립트

N
s/\n/ /

한 줄을 읽은 다음 N명령 에 의해 삽입 된 포함 된 줄 바꿈을 사용하여 다음 줄을 추가하고 그 줄 바꿈을 공백 (및 출력)으로 바꾸 므로 예상 한대로 작동하지 않습니다 . 이후 줄을 읽을 때 처음 두 줄의 결과는 무시됩니다.

대신 홀드 공간을 사용해야했습니다.

H;            # append to hold space with a '\n' embedded
              # for the last line:
${
    x;        # swap in the hold space
    s/\n//;   # delete the first newline (from the H command on the very first line of input)
    y/\n/ /;  # replace all other newlines with spaces
    p;        # print result
}

이 스크립트는 각 입력 라인마다 한 번씩 실행되며 마지막 라인에 도달 할 때까지 보류 공간에서 데이터를 수집합니다. 마지막 줄에서 수집 된 데이터를 처리하여 출력합니다.

당신은 이것을 다음과 sed -n같이 실행할 것입니다 :

$ sed '=' <file2 | sed -n 'H; ${ x; s/\n//; y/\n/ /; p; }'
1 this is  2  not is  3  is is  4  this biz

(입력 끝에 줄이 없었기 때문에 출력 끝에 줄 바꿈이 없음).

또는 명시적인 루프를 사용하여 사용할 수 있습니다 N. 여기서 트릭은 결과를 인쇄 할 준비가 될 때까지 스크립트 끝에 도달하지 않는 것입니다.

:top;     # define label 'top'
N;        # append next line with a '\n' embedded
$!btop;   # if not at end, branch to 'top'
y/\n/ /;  # replace all newlines with spaces
          # (implicit print)

이 스크립트는 한 번만 실행되고 데이터 자체의 읽기를 관리하는 반면 이전 스크립트는 내장 된 읽기 루프에 의해 데이터가 공급됩니다 sed(이는 각 라인 읽기 의 패턴 공간대체합니다 ). 보류 공간 대신 ​​패턴 공간을 사용하여 데이터를 수집하고 마지막 행을 읽을 때 처리합니다.

명령 행에서 :

$ sed '=' <file2 | sed ':top; N; $!btop; y/\n/ /'

(위와 동일한 출력)


두 솔루션 모두 전체 파일을 메모리에 저장합니다.
Isaac Isaac

@Isaac 네, sed로이 작업을 수행하는 것의 단점입니다.
Kusalananda

sed 명령에 대한 간결한 설명에 감사드립니다. 너무 많은 사람들이 작동하는 이상한 이상한 명령을
내리지 만

4

GNU sed라면 이것을 시도하십시오

$ sed -z 's/\n/ /g' file2
this is   not is   is is   this biz
$

tr 똑같이 잘합니다.

$ tr '\n' ' ' <file2
this is   not is   is is   this biz
$

솔루션에 대해 감사하지만 sed 삽입 된 줄 바꿈 만 제거하는 이유가 궁금합니다.
리눅스 초보자

1
paste -sd" "파일의 줄을 결합하는 데에도 좋습니다. 보너스로 후행 줄 바꿈을 유지합니다.
glenn jackman 2016 년

3

이것은 근본적 sed으로 선 지향적 이기 때문 입니다. 무슨 일이야

  • sed는 첫 번째 라인 1을 패턴 공간으로 로드합니다
  • N명령은 다음 줄을로드하고로 구분 패턴 공간에 추가합니다 \n, 제공1\nthis is
  • 우리 \n는 공간 제공으로 대체1 this is

그리고 우리는 끝났습니다. 패턴 공간이 인쇄 된 다음 나머지 (쌍) 라인마다 단계가 반복됩니다.


그러나 printf 명령을 사용하여 직접 삽입 한 새 줄은 어떻습니까? 왜 sed가 그것들을 인식 할 수 없습니까?
리눅스 초보자

@LinuxNewbie sed스크립트 에서는 원본 데이터에있는 줄 바꿈이 표시 되지 않습니다 . 대체하는 줄 바꿈은 N삽입 하는 줄 바꿈입니다 . 스크립트는 한 줄씩 데이터를 읽고 각 줄의 끝에서 줄 바꿈을 제거합니다.
Kusalananda

0

사용한 명령은 라인을 쌍으로 만 처리합니다 .
첫 번째 줄은 줄 번호입니다 ( =명령으로 인쇄 ).
두 번째 줄은 첫 번째 줄에 추가되고 한 줄 바꿈이 제거되고 인쇄됩니다.
그런 다음 다음 라인 쌍이 동일하게 처리됩니다.

모든 라인 을 처리하는 유일한 방법 은 마지막 라인까지 누적하는 것입니다.
이 때 모든 줄 바꿈을 지우거나 공백으로 변환 할 수 있습니다.

$ sed '=' file | sed ':start;N;$bend;bstart;:end;y/\n/ /'
1 this is  2  not is  3  is is  4  this biz

더 짧은 줄 (그러나 더 느린 줄도이 매우 짧은 파일의 문제는 아님)은 다음과 같습니다.

sed ':1;N;s/\n/ /;t1'

위의 두 솔루션 모두 전체 파일을 메모리에 저장합니다.

그러나 물론 tr이 작업에 더 좋은 도구입니다.

$ sed '=' file | tr '\n' ' '

또는 paste(후행 줄 바꿈 유지) :

$ sed '=' file | paste -sd ' '
1 this is  2  not is  3  is is  4  this biz

0

아래 명령으로 시도했지만 정상적으로 작동했습니다.

inputfile

this is
 not is
 is is

명령:

cat inputfile|sed "="| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"

산출

1 this is  2  not is  3  is is  4  this biz

이것은 효과가 있지만 sed파일에 줄이있는 것만 큼 빼기 위해 해당 스크립트의 사본을 추가해야합니다 .
Kusalananda
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.