두 패턴 사이의 모든 내용을 인쇄한 다음 결과 출력의 첫 번째 줄과 마지막 줄을 제거합니다.

두 패턴 사이의 모든 내용을 인쇄한 다음 결과 출력의 첫 번째 줄과 마지막 줄을 제거합니다.
otherdata
otherdata
start_data
one
two
three
four
end_data
otherdata
otherdata

결과 출력은 다음과 같아야 합니다.

one
two
three
four

sed이것은 나에게 직업처럼 보입니다.

sed -n '/start_data/,/end_data/{1d;$d;p}' myfile

작동 안함. 첫 번째 행은 삭제되지만 마지막 행은 삭제되지 않습니다. (지금까지는 어떤 이유도 논리로 설명할 수 없습니다)

음, 추악한 방법을 시도해 봅시다:

sed -n '/start_data/,/end_data/{/start_data\|end_data/!p}' myfile

공평하게 말하면 이것이 작동합니다. 그러나 나는 더 짧은 방법도 작동하기를 원합니다.결과출력은 다음과 같습니다언제나중간에 있는 데이터만 추출하므로 첫 번째 행과 마지막 행에는 두 패턴이 모두 포함됩니다.

중괄호 안에 and 문을 결합 sed하려고 하면 왜 숨이 막힐까요?1d$d

답변1

논리를 반대로 바꿀 수 있습니다.

sed '1,/start_data/d;/end_data/,$d'

start_data첫 번째 줄에 없다고 가정합니다 . 이 문제를 해결하려면 GNU가 있는 경우 sed대신 다음을 수행할 수 있습니다.

sed '0,/start_data/d;/end_data/Q'

그것은 GNU에만 해당 0됩니다 Q. 패턴 공간을 인쇄하지 않고 Q종료 sed하므로 첫 번째 솔루션처럼 파일의 나머지 부분을 계속 읽고 삭제하지 않으므로 더욱 효율적입니다.

답변2

awk이 질문에 적합한 것 같습니다.

$ awk '/end_data/{f=0;};f{print;};/start_data/{f=1;}' myfile
one
two
three
four

위의 내용은 플래그를 사용하여 f줄을 인쇄할지 여부를 결정합니다. 이면 start_data플래그가 true(1)로 설정됩니다. 발견 되면 end_data이 플래그는 false(0)로 설정됩니다. true 이면 f행이 인쇄됩니다.

중괄호 안에 1d와 $d 문을 결합하려고 할 때 sed가 질식하는 이유는 무엇입니까?

이것은 "질식"이 아닙니다. 패턴의 첫 번째 줄과 마지막 줄은 참조하지 않고 파일의 첫 번째 줄과 마지막 줄만 1d참조합니다 .$d

답변3

음, 이것은 작동합니다:

sed -ne/start_data/!d\;:n -e'n;/end_data/q;p;bn' <in

p해당 주소에서 마지막 줄을 만나서 이동할 때까지 린트를 시도하지 않습니다 /start_pattern/. 개행이 일치하는 항목을 가져오면 n현재 행을 ext, uit 입력으로 완전히 대체하고, 그렇지 않으면 린트합니다. 이게 다야. 샘플 데이터를 기반으로 출력은 다음과 같습니다.q/end_data/p

one
two
three
four

한 줄을 다음과 같이 인식하지 못합니다.end_data첫 번째 항목과도 ​​일치하면 일치합니다.start_data입력에 나타나는 줄입니다.

답변4

여기서는 질문에 제공된 입력 파일을 간단하게 수정해 보겠습니다.

% cat myfile
red
orange
start_data
one
two
three
four
end_data
yellow
green

나는 단지 otherdata다른 데이터로 줄을 대체하여 "첫 번째 줄"이라고 말할 필요 없이 입력 파일의 각 줄을 해당 내용으로 고유하게 참조할 수 있도록 했습니다. "첫 번째 줄 otherdata"은 약간 길기 때문입니다( 그리고 내가 이해하는 바로는 오해될 수도 있습니다.)

이제 첫 번째 시도에 가장 가까운 것은 다음과 같습니다.

% sed -n '/start_data/,/end_data/p' myfile | sed '1d;$d'
one
two
three
four

sed -n '/start_data/,/end_data/{1d;$d;p}' myfile(John1024가 말했듯이) line 1redline * 이고 line $greenline ** 이기 때문에 첫 번째 try( ) "초크"입니다 . 1d;$d;이 줄(실제로 는모두/colordata 라인 ) 이 범위에서 제외 otherdata되었습니다 . __________ * 즉, 첫 번째 줄/start_data/,/end_data/

모두
일치하는 범위 ** 뿐만 아니라 입력 파일, 즉 마지막 줄모두일치 범위뿐만 아니라 입력 파일


그런데, 귀하의 명령이 다음과 같은 출력을 생성한다는 말씀이신가요?

one
two
three
four
end_data

그렇지 않으면 의미가 없기 때문입니다.start_data 예전에는라인 1(즉, 존재하지 red않는 경우 orange)

관련 정보