두 번째 줄 바꾸기 [닫기]

두 번째 줄 바꾸기 [닫기]

yyyy-mm-dd hh:mm:ss아래 파일에서 첫 번째 항목을 제외한 모든 항목을 제거 하고 싶습니다 . 그래서 기본적으로 나는 행의 첫 번째 발생을 표시하고 나머지 모든 중복 행을 제거하고 싶습니다. 정규식 cmd를 사용하여 이 작업을 수행하도록 도와줄 수 있는 사람이 있습니까?

Will use per-minute statistics
Stats from 2016-06-26   00:00:00 to 2016-06-26  23:59:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
6/26/2016       0:03:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
6/26/2016       0:02:00
6/26/2016       0:03:00

답변1

중복된 yyyy-mm-dd 줄을 모두 제거하려면

% sed '/^yyyy-mm-dd/,$ { n ; /^yyyy-mm-dd/d }' srcfile
Will use per-minute statistics
Stats from 2016-06-26   00:00:00 to 2016-06-26  23:59:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
6/26/2016       0:03:00
6/26/2016       0:01:00
6/26/2016       0:01:00
6/26/2016       0:02:00
6/26/2016       0:03:00

모든 중복 행을 제거하려는 경우 이는 약간 해킹적이고 비효율적이지만 작동하고 이해하기 쉽습니다. (두 번째 sed|grep을 최적화할 수 있지만 읽기가 더 쉽습니다. IMHO).

% sed -n '1,/^yyyy-mm-dd/p' srcfile ; sed '1,/^yyyy-mm-dd/d' srcfile | grep -v ^yyyy-mm-dd | sort -u
Will use per-minute statistics
Stats from 2016-06-26   00:00:00 to 2016-06-26  23:59:00
yyyy-mm-dd      hh:mm:ss
6/26/2016       0:01:00
6/26/2016       0:02:00
6/26/2016       0:03:00

답변2

올바른 도구는 awk입니다. 간단한 방법으로 논리를 표현할 수 있습니다. seen패턴이 처음 표시될 때 변수를 설정하고, 패턴이 이미 표시된 경우 패턴과 일치하는 줄을 건너뜁니다. 줄을 건너뛰지 않았다면 인쇄하세요.

awk '/^yyyy-mm-dd[ \t]+hh:mm:ss$/ {if (seen) next; ++seen}
     1 {print}'

이는 축약될 수 있지만 더욱 비밀스러워집니다.

awk '!(/^yyyy-mm-dd[ \t]+hh:mm:ss$/ && !(seen++))'

답변3

sed -e '0,/^yyyy-mm-dd\s\+hh:mm:ss$/!{/^yyyy-mm-dd\s\+hh:mm:ss$/d}'

(GNU sed 기능) 범위는 0,/pattern/첫 번째 항목과 일치하므로 0,/pattern/!파일의 나머지 부분을 실행하여 후속 일치 항목을 모두 제거합니다.{...}

답변4

GNU는 정규식 주소의 숫자 오프셋을 지원하므로 ed파일 끝까지의 범위를 지정할 수 있습니다. 그런 다음 해당 범위에서 동일한 정규식과 일치하는 줄을 삭제할 수 있습니다. 마지막으로 수정된 파일을 작성하고 종료합니다. /pattern/+1$g//d

ed file << EOF
/^yyyy-mm-dd/+1,$ g//d
wq
EOF

또는 동등하게

 printf '/^yyyy-mm-dd/+1,$ g//d\nwq\n' | ed file

관련 정보