X~Y 행이 충족하는 조건에 대해서만 텍스트 처리를 수행합니다.

X~Y 행이 충족하는 조건에 대해서만 텍스트 처리를 수행합니다.

X에서 Y까지의 줄에만 표시되는 중복 줄을 제거하고 파일을 제자리에서 변경하려면 어떻게 해야 합니까?

예를 들어, 10행에서 20행까지 중복된 행만 제거하려는 경우입니다.

답변1

GNU 사용 awk(4.1.0 이상 inplace확장 1):

gawk -i /usr/share/awk/inplace.awk '
  NR >= 10 && NR <= 20 {
    if ($0 in seen) next
    seen[$0]
  }
  {print}' ./file

또는 다음을 사용하여 perl:

perl -ni -e 'print if $. < 10 or $. > 20 or !$seen{$_}++' ./file

여러 파일 처리:

gawk -i /usr/share/awk/inplace.awk '
  BEGINFILE{delete seen}
  FNR >= 10 && FNR <= 20 {
    if ($0 in seen) next
    seen[$0]
  }
  {print}' ./*.txt

또는 다음을 사용하여 perl:

perl -ni -e '
  print if $. < 10 or $. > 20 or !$seen{$_}++;
  if (eof) {close ARGV; undef %seen}' ./*.txt

^사용하지 마세요-i inplace현재 작업 디렉터리(as or)에서 확장 기능을 먼저 gawk로드 하려고 하면 누군가가 해당 디렉터리에 악성 코드를 심었을 수 있습니다. 시스템과 함께 제공되는 확장 프로그램 의 경로 는 다를 수 있습니다. 출력을 참조하세요.inplaceinplaceinplace.awkinplacegawkgawk 'BEGIN{print ENVIRON["AWKPATH"]}'

답변2

awk당신의 친구입니다

awk '{
      if(NR>=10 && NR<=20)
      {
        if($0 in record){
         next
        }else{
         print;
         record[$0];
        }
     }
     else{
        print
     }
     }' file > temp && mv temp file

답변3

OP가 10~20개 행 내의 중복 행을 삭제해야 하는 경우:

sed -i '
    :a; 10,19!b; N; s/\(^\|\n\)\([^\n]*\)\n\(\(.\+\n\|\)\2$\)/\1\3/; ba
       ' file1 file2 ...

답변4

Perl 기반 답변에 적용된 동일한 트릭을 사용하여 Awk 코드를 단축할 수도 있으며 결과적으로 더 작고 깔끔해집니다.

awk 'NR < 10 || NR > 20 || !seen[$0]++'
   ^ ^          ^           ^
   | |          |           |
   | \__________\___________\______ no sigil noise
   |
   \_ no options here to remember
      (unless we want that Gawk inplace semantics)

범위가 10줄로 제한되어 있고 GNU Awk에는 어쨌든 큰 정수가 있기 때문에 카운터가 오버플로되지 않습니다.

관련 정보