Linux 명령을 사용하여 파일의 하위 제목 아래 줄을 삭제하는 방법

Linux 명령을 사용하여 파일의 하위 제목 아래 줄을 삭제하는 방법

아래와 같은 파일이 있습니다. 특정 부제목 아래의 행을 개별적으로 삭제하고 싶습니다. sed 및 awk 명령을 사용해 보았지만 얻을 수 없었습니다. 이 문제를 해킹하기 위해 일부 Linux 명령을 사용하는 데 도움을 줄 수 있는 사람이 있습니까?

[first attempt]
a=10
b=20

[second attempt]
a=20
b=20

[third attempt ] 
a=30
b=50

"[두 번째 시도]" 하위 제목 아래의 행을 개별적으로 제거하고 싶습니다. 출력은 아래와 같아야 합니다. 부제목 아래의 콘텐츠만 삭제하고 선택적으로 삭제된 행을 빈 행으로 바꾸고 싶습니다.

[first attempt]
a=10
b=20

[second attempt]

[third attempt ] 
a=30
b=50

답변1

awk -v blkid=0 -v rmblk=2 '{
      if ( $1 ~ /^\[/) {
            blkid+=1;blkn=NR;print };
      if ( blkid !=rmblk && NR!=blkn )
            print ;
      else if(blkid ==rmblk && NF == 0)
                  print ""}' file.txt

각 블록의 ID는 1에서 시작하여 각 블록에 대해 1씩 증가합니다 blkid.

삭제하려는 블록의 블록 ID:rmblk

각 블록은 첫 번째 필드가 로 시작될 때 시작됩니다 [.

이 변수는 blknNR 값 [first attempt] [second attempt]등을 저장합니다.

답변2

sed '$!N;/^\[second/,/^\n\[/P;D' <infile >outfile

다음 부분 앞에 오는 빈 줄을 어떻게 처리할지 잘 모르겠지만 아마도 작동할 것입니다. 이 출력에는 올바른 일인 것처럼 보이기 때문에 이를 포함하지만, 임의의 섹션에서 마지막 빈 줄을 제거하려는 경우 비교적 쉽게 수행할 수 있으므로 물어보십시오.

!기본적으로 마지막 행이 아닌 모든 입력 행에 대해 $추가 행도 sed삽입되어 삽입된 줄 바꿈 문자 구분 기호 뒤의 패턴 공간 N에 추가됩니다 . \n이런 일이 발생할 때마다 패턴 공간이 변경됩니다.

 ^Line1\nLine2$
 ^Line2\nLine3$
 ^Line3\nLine4$

현재 패턴 공간이 패턴과 일치하는 경우^\[second또는^\n\[또는 그 사이에 나타나는 모든 라인은 패턴 공간에서 처음 으로 나타나는 ewline에 인쇄됩니다 sed. 따라서 각 반복은 버퍼의 절반만 인쇄합니다.P\n

마지막으로, 패턴 공간에서 처음 나타나는 ewline을 sed D삭제 \n하고 위에서부터 스크립트를 다시 시작합니다. 이것이 시프트 효과를 얻는 방법입니다. 이것은 ... 불리운다슬라이딩 윈도우. 그것은 매우 잘 작동하고 매우 빠릅니다.


이 문제에는 여러 버전이 있는 것 같은데요? 어쨌든 반대 방향으로 가는 것은 그리 어렵지 않습니다.

당신은 이것을 할 수도 있습니다 ...

sed -ne '/^\[[^s]/,/^\[s/p' <in >out

s이는 문자로 시작하는 제목 과 모든 제목을 따르지 않는 모든 항목을 인쇄합니다 . 그러나 다음 이후에는 깔끔한 작은 개행 문자를 수행하지 않습니다.


[first attempt]
a=10
b=20

[second attempt]
[third attempt ]
a=30
b=50

좀 더 명확하게 하고 싶다면 다음과 같이 할 수도 있습니다.

sed '/^\[[second]/P;$!N;//,/\n$/!P;D' <in >out

...이것은 깔끔하게 약간의 줄 바꿈을 수행합니다...

[first attempt]
a=10
b=20

[second attempt]

[third attempt ]
a=30
b=50

이들 모두는 sed다음과 같이 일치하는 각 표현식에 대한 범위입니다.

/match1/,/match2/command

... sed적용됩니다command두 개의 일치하는 줄과 그 사이의 모든 줄로.

답변3

이 작업을 수행하려면 짧은 스크립트를 사용할 수도 있습니다 sed. 파일에 다음 내용을 넣으세요.

/second/ {
   n
   : del
   /./ ! b
   N
   s/.*\n//
   b del
}

불러라 script. 그런 다음 을 사용하세요 sed -f script myfile. 파일을 제자리에서 편집하려면 을 사용하세요 sed -i -f script myfile. 하지만 시도하기 전에 첫 번째 명령을 실행하고 원하는 출력이 맞는지 확인하는 것이 좋습니다.

설명하다:

문자열을 찾으면 secondsed는 다음 줄을 살펴봅니다. 해당 줄이 비어 있지 않으면 해당 줄을 버리고 빈 줄을 찾을 때까지 파일의 다음 줄을 살펴보세요. 이 빈 줄과 파일의 다른 모든 줄이 인쇄됩니다. (문자열을 포함하는 다른 행이 없으면 second프로세스가 반복됩니다.)

(관심 있으신 분 계시면 자세히 설명드리겠습니다.)

답변4

나는 "두 번째 시도"와 "세 번째 시도"라는 두 줄 번호로 greping을 시도한 다음 그 사이의 모든 항목을 삭제합니다. 필요에 맞게 적절하게 편집하세요. :)

#getting line number for [second attempt]
line_num_second=$(grep -n "second attempt" yourfile.txt | cut -d : -f 1)

#getting line number for [third attempt]
line_num_third=$(grep -n "third attempt" yourfile.txt | cut -d : -f 1)

start=$(expr $line_num_second +1)
end=$(expr $line_num_third -2)

#removes the content in between [second attempt] and [third attempt]
sed $start,"$end"d yourfile.txt

# sed -i $start,"$end"d yourfile.txt # -i - overwite/edit your files in-place instead of printing to standard output

관련 정보