나는 이것을 사용한다
cat foo.txt | sed '/bar/d'
bar
이 문자열이 포함된 파일의 줄을 삭제합니다 .
하지만 이 줄을 삭제하고 싶어요그리고 바로 다음 줄은. MinGW32에서 사용 가능한 다른 도구를 사용하는 sed
것이 좋습니다 .awk
이는 일치하는 줄 과 일치하는 줄 앞/뒤의 줄을 grep
인쇄할 수 있는 위치와 반대입니다 .-A
-B
이를 달성하는 간단한 방법이 있습니까?
답변1
GNU sed(내장되지 않은 Linux 또는 Cygwin)가 있는 경우:
sed '/bar/,+1 d'
bar
행에 두 개의 행이 있는 경우 두 번째 행을 구문 분석하지 않고 삭제합니다. 예를 들어 bar
// 3줄 파일이 있는 경우 bar
해당 foo
줄은 foo
유지됩니다.
답변2
bar
연속된 줄에 표시할 수 있는 경우 다음과 같이 할 수 있습니다.
awk '/bar/{n=2}; n {n--; next}; 1' < infile > outfile
위의 2를 삭제할 행 수(일치하는 행 포함)로 변경하여 2개 이상의 행을 삭제하는 경우에 적용할 수 있습니다.
그렇지 않으면 쉽게 sed
할 수 있습니다@MichaelRollins의 솔루션또는:
sed '/bar/,/^/d' < infile > outfile
답변3
나는 sed에 별로 익숙하지 않지만 awk에서는 이 작업을 쉽게 수행할 수 있습니다.
awk '/bar/{getline;next} 1' foo.txt
awk 스크립트의 내용은 다음과 같습니다. bar가 포함된 줄에 대해 다음 줄(getline)을 가져온 다음 모든 후속 처리를 건너뜁니다(next). 끝에 있는 1 패턴은 나머지 줄을 인쇄합니다.
고쳐 쓰다
의견에서 지적했듯이 위의 솔루션은 인접한 솔루션에서는 작동하지 않습니다 bar
. 다음은 이를 고려한 수정된 솔루션입니다.
awk '/bar/ {while (/bar/ && getline>0) ; next} 1' foo.txt
이제 모든 /bar/ 줄을 건너뛰고 계속해서 읽어보겠습니다.
답변4
일치 항목 바로 다음 행을 삭제해야 하는 경우 sed
프로그램은 연속 일치 항목을 고려해야 합니다. 즉, 일치 후 줄을 삭제하고 해당 줄도 일치하는 경우 해당 줄 다음 줄도 삭제해야 할 것입니다.
구현하는 것은 매우 간단하지만 약간의 과정을 거쳐야 합니다.
printf %s\\n 0 match 2 match match \
5 6 match match match \
10 11 12 match 14 15 |
sed -ne'x;/match/!{g;//!p;}'
0
6
11
12
15
읽은 각 라인에 대해 홀드 공간과 패턴 공간을 교체하여 작동하므로 매번 마지막 라인을 현재 라인과 비교할 수 있습니다. 따라서 sed
한 줄을 읽으면 해당 버퍼의 내용이 교체됩니다. 이전 줄은 편집 버퍼의 내용이고 현재 줄은 예약된 공간에 배치됩니다.
sed
이전 행에 일치하는 항목이 있는지 확인하세요 .match
, 찾을 수 없는 경우 !
함수에서 두 표현식을 실행합니다. 패턴 공간을 덮어써 예약된 공간을 설정합니다. 즉, 현재 줄은 예약된 공간과 패턴 공간 모두에 있습니다. 그런 다음 가장 최근에 컴파일된 정규 표현식과 일치하는지 확인합니다.{
}
sed
g
//
match
- 만약에그것확실히match
인쇄 되었습니다 p
.
이는 라인이 존재하지 않는 경우에만 인쇄된다는 것을 의미합니다.match
그리고바로 앞 줄에는 해당 내용이 없습니다.match
. 또한 불필요한 시퀀스 교환을 포기합니다.match
예.
원하는 경우 다음에서 삭제할 수 있습니다.match
더 많은 작업이 필요합니다.
printf %s\\n 1 2 3 4 match \
match match 8 \
9 10 11 12 13 \
14 match match \
17 18 19 20 21 |
sed -net -e'/match/{h;n;//h;//!H;G;s/\n/&/5;D;}' -ep
...5를 행 수로 바꿉니다.(일치하는 라인 포함)삭제하고 싶은 내용...
1
2
3
4
12
13
14
21