file_a.txt라는 텍스트 파일이 있습니다. 내 첫 번째 명령은
grep -A 12 ".production =" file_a.txt
출력은 여러 블록입니다. 각 문자열 블록에는 13줄이 포함되어 있습니다.
grep
특히 원본 파일 file_a.txt에서 명령을 사용하여 얻은 모든 문자열 블록을 제거하고 싶습니다. grep 출력을 새 파일로 보내고 싶지 않습니다. grep -v
내 경우에는 작동하지 않기 때문에 둘 중 하나를 사용하고 싶지 않습니다 .
비슷한 것을 시도했지만 아무것도 작동하지 않습니다.
cut < grep -A 12 ".production =" file_a.txt
sed -i '/`grep -A 12 ".production ="`/d' file_a.txt
답변1
GNU sed 모드
(일부 Linux 배포판을 사용하는 경우 GNU sed
기본 구현이어야 함 sed
) 다음과 같이 사용할 수 있습니다.
sed '/.production =/,+12d' inputfile.txt
작동 방식:
- 입력 파일을 한 줄씩 스캔하고(sed가 작동하는 방식) 명령을 사용해야 하는지 여부를 확인합니다.
- 우리의 명령은
d
(마지막 문자)입니다. 이는 행 삭제를 의미합니다. - 하지만 이 명령은 현재 행이 범위와 일치하는 경우에만 실행됩니다.
- 범위는 범위의 시작과 끝을 포함하여 문자로 구분된 두 개의 매개변수로 지정됩니다
,
. 첫 번째는/.production =/
표현식이 포함된 모든 행과 일치하는 정규 표현식입니다 . 두 번째 매개변수는+12d
을 의미합니다12 lines from start range
. - 따라서 범위는 표현식과 일치하는 모든 행과 다음 12개 행을 일치시키고 삭제합니다.
- 다른 모든 행은 출력으로 인쇄됩니다(기본값
sed behaviour
).
휴대용, 추악한 방법
이는 다른 sed
구현과 함께 작동해야 하지만 더 많은 입력이 필요하고 강력하지 않습니다.
sed '/.production =/{N;N;N;N;N;N;N;N;N;N;N;N;d}' somefile.txt
작동 방식:
- 입력 파일을 한 줄씩 스캔하고(sed가 작동하는 방식) 명령을 사용해야 하는지 여부를 확인합니다.
/.production =/
선이 패턴과 일치하는지 확인합니다 . 그렇다면 중괄호로 묶인 모든 명령을 실행합니다{}
.- 우리는
N
명령을 12번 실행했습니다.N
이 명령은 다음 줄을 읽고 이를 현재 버퍼에 추가합니다. 따라서 12회 실행 후에는 13개 라인이 현재 버퍼에 연결됩니다(첫 번째 라인 +N
명령으로 읽은 12개 라인). d
이제 연결된 13개 라인을 삭제하는 명령을 실행합니다 .sed
다른 패턴을 찾을 때까지 계속하고 행 13을 다시 삭제합니다. 다른 모든 줄은 인쇄됩니다(기본sed
동작).
답변2
필터링을 시작하려는 행 번호를 검색한 다음 AWK를 사용하여 필터링할 수 있습니다.
AWK에서 NR은 레코드 번호를 나타내며 기본값은 줄 끝(\n)입니다.
START_LINE=$(cat file_a.txt | grep -n .production | cut -f1 -d:)
cat file_a.txt | awk '{ if(NR < '$START_LINE' || NR > '$START_LINE' + 12) print $0; }'
답변3
grep과 sed로 문제를 완전히 해결할 수 없는 경우 awk를 사용할 수 있습니다. awk는 대부분의 텍스트 유틸리티를 쉽게 에뮬레이트할 수 있으며( sort
이것은 주요 예외임) 파이프보다 더 유연한 방식으로 결합할 수 있습니다.
awk '
/.production =/ {skip_lines = 13}
skip_lines {--skip_lines}
!skip_lines {print}
' file_a.txt >file_a.txt.new &&
mv file_a.txt.new file_a.txt
답변4
Ex 모드에서 Vim을 사용할 수 있습니다:
ex -sc '/.production =/d13|x' file_a.txt
//
일치하는 행으로 이동13
13행을 선택하세요.d
삭제x
저장하고 닫습니다