아래와 같은 파일이 있습니다. 특정 부제목 아래의 행을 개별적으로 삭제하고 싶습니다. 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
각 블록은 첫 번째 필드가 로 시작될 때 시작됩니다 [
.
이 변수는 blkn
NR 값 [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
. 하지만 시도하기 전에 첫 번째 명령을 실행하고 원하는 출력이 맞는지 확인하는 것이 좋습니다.
설명하다:
문자열을 찾으면 second
sed는 다음 줄을 살펴봅니다. 해당 줄이 비어 있지 않으면 해당 줄을 버리고 빈 줄을 찾을 때까지 파일의 다음 줄을 살펴보세요. 이 빈 줄과 파일의 다른 모든 줄이 인쇄됩니다. (문자열을 포함하는 다른 행이 없으면 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