캐리지 리턴(\r)이 포함된 줄의 전부는 아니지만 대부분 삭제

캐리지 리턴(\r)이 포함된 줄의 전부는 아니지만 대부분 삭제

캐리지 리턴(\r)이 포함된 상태 줄을 너무 많이 출력하는 프로세스가 있습니다. 파이핑을 통해 이러한 모든 상태 표시줄을 필터링할 수 있습니다.

sed '/\r/d' 

대신 3행을 제외한 모든 행을 필터링하고 싶습니다. 표준 Unix 도구(awk?)를 사용하여 이 작업을 수행할 수 있습니까? 아니면 스크립트가 필요합니까? CR이 없는 행은 변경되지 않은 상태로 유지되어야 합니다.

주어진 출력:

$ (printf '%s\n' {1..10};   printf  '%s\r\n' {1..10}; printf '%s\n' {1..10};)  | cat -v
1
2
3
4
5
6
7
8
9
10
1^M
2^M
3^M
4^M
5^M
6^M
7^M
8^M
9^M
10^M
1
2
3
4
5
6
7
8
9
10

원하는 출력(또는 기타 패턴):

1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10

답변1

$ awk '!(/\r$/ && ((++c)%3 != 1))' file | cat -v
1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10

원래 답변:

awk를 사용하면 필요한 것은 이것뿐입니다.

awk -v RS='\r' '{ORS=(NR%10000 ? "" : RS)} 1'

예를 들어 입력으로 사용하는 경우:

$ printf '%s\r\n' {1..10} | cat -v
1^M
2^M
3^M
4^M
5^M
6^M
7^M
8^M
9^M
10^M

3개를 제외하고 모두 삭제 \r:

$ printf '%s\r\n' {1..10} | awk -v RS='\r' '{ORS=(NR%3 ? "" : RS)} 1' | cat -v
1
2
3^M
4
5
6^M
7
8
9^M
10

답변2

를 사용하여 GNU sed계산을 위해 예약된 공간을 사용합니다.

sed -E '
  /\r$/{
    G;/\n$/P
    s/.*\n/./
    /.{3}/z;x;d
  }
' file

를 사용하여 awk변수 c를 3에 도달하면 재설정되는 루프 카운터로 사용합니다.

awk '
!/\r$/ || !c++
c==3{c=0}
' file

\r캐리지 리턴( ) 문자가 나타날 때마다 줄 바꿈( )으로 구분된 레코드의 끝에 발생한다고 가정합니다 .\n

답변3

awk에서 이 작업을 수행하는 특별한 방법은 다음과 같습니다.

{m,g}awk '((+$_ % 3) % NF)~(!_<NF)' FS='\r$'  # yes that's a 
                                              # tilde ~ not a minus -

1
2
3
4
5
6
7
8
9
10
1^M
4^M
7^M
10^M
1
2
3
4
5
6
7
8
9
10

같은 것을 표현하는 다른 방법

mawk 'NF-!_== (+$+_   %    3    ) % NF' FS='\r$'
gawk 'NF-!_== ( $(_++)%(_+_+_--)) % NF' FS='\r$'

관련 정보