많은 줄이 포함된 파일에서 세 번째 줄 뒤의 두 줄을 모두 삭제하는 방법은 무엇입니까? [복사]

많은 줄이 포함된 파일에서 세 번째 줄 뒤의 두 줄을 모두 삭제하는 방법은 무엇입니까? [복사]

내가 가지고 있는 것처럼
:

1st line (keep)  
2nd line (keep)  
3rd line (keep)  
4rth lines (delete)  
5th (del)  
6th (keep)  
7nth (keep)  
8th lines  (keep)  
9th (del)  
10th (del)  
11th (keep)  
12th (keep)  
13th (keep)  
14th (del)  
15th (del)  

등....

답변1

노력하다:

awk '(NR-1)%5<3' file

예를 들어:

$ awk '(NR-1)%5<3' file
1st line (keep)
2nd line (keep)
3rd line (keep)
6th (keep)
7nth (keep)
8th lines (keep)
11th (keep)
12th (keep)
13th (keep)

어떻게 작동하나요?

이 명령은 true 인 모든 행을 인쇄하도록 (NR-1)%5<3지시합니다 . in 은 줄 번호이고 첫 번째 줄 개수는 입니다 . 파일의 다섯 줄마다 이 문은 처음 세 줄에 적용됩니다.awk(NR-1)%5<3awkNR1

답변2

간단한 명령은 다음과 같습니다:

awk '{if((NR-1) % 5<=2){print $0}}' file

5줄의 순서로 처음 3줄만 인쇄합니다. (NR-1)%5비슷한 출력을 제공 0 1 2 3 4하고 처음 3개 행이 2보다 작거나 같기 때문입니다 . 그래서 그냥 인쇄할 것입니다.

내용이 포함된 파일이 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

출력은 다음과 같습니다

1
2
3
6
7
8
11
12
13

또는 의견에서 제안한 대로 다음을 사용할 수 있습니다.

awk '(NR - 1) % 5 <= 2' file

답변3

기본적으로 awk에서는 "Fizz-Buzz"와 같은 것을 원합니다.

awk '{ if (i++%5 < 3) print $0;}'

이 작품을 선보이기 위해...

for x in 1 2 3 4 5 6 7 8 9 10 ; do echo $x; done |
awk '{ if (i++%5 < 3) print $0;}'

파일 이름이 "mybigfile.csv"인 경우,

awk '{ if (i++%5 < 3) print $0;}' < mybigfile.csv > mybigfile-123.csv

답변4

이 문제는 GNU를 사용하여 해결할 수 있습니다 sed.

sed '4~5,5~5d' file

이는 sed에 대한 표준 GNU 특정 확장을 사용하므로 macOS 등의 BSD sed에서는 작동하지 않습니다. 그러나 GNU sed는 macOS를 사용하여 설치할 수 brew있으며 gsedLinux에서는 GNU sed가 기본값입니다.

이는 4~5행에 속하지 않는 5개 행의 모든 ​​행을 인쇄합니다. 더 명확한 예: sed '3~10,6~10d'행 3~6, ​​10줄을 삭제하여 10개의 각 그룹에서 1, 2, 7, 8, 9행을 채웁니다.

awk '(NR-1)%5<3'내 컴퓨터에서는 1~200만 개의 숫자가 포함된 파일의 경우 약 0.6초가 걸리는 반면, 이 답변의 sed 솔루션은 약 0.35초가 걸립니다 . sed는 일반적으로 더 간단한 도구이므로 더 복잡하지만 모든 기능을 갖춘 awk보다 빠르게 작동하기 때문에 이는 합리적입니다.

관련 정보