열 수 = 0.00000000을 기준으로 파일 행 필터링

열 수 = 0.00000000을 기준으로 파일 행 필터링

열 5 이후의 열 수를 기준으로 파일 행(예: 아래 file.txt)을 필터링하고 싶습니다 =0.00000000.

아래 I/O는 예를 보여줍니다.값이 0인 2개 이상의 열(열 5 이후)이 있는 행을 필터링합니다. 또는=0.00000000(즉, 값이 0인 열이 두 개 이상 있는 행을 삭제하거나 값이 0이 아닌 열이 6개 미만인(열 5 이후) 행을 삭제합니다.)

1개, 2개 또는 3개 이상의 열(5번째 열 이후)이 있는 행을 필터링하도록 결정할 수 있도록 이 작업을 유연하게 수행할 수 있는 방법이 있습니까?=0.00000000

실제 파일에는 수천 개의 행과 61 또는 71개의 열이 있지만 처음 5개 열은 동일합니다.

파일.txt

MT 227 1 1.000 42.0 1:2=0.00036000 1:3=0.00000000 1:4=0.00004200 1:5=0.04300000 1:6=0.03400000 1:7=0.00000000 1:8=0.01204819
MT 233 1 1.000 60.0 1:2=0.10000000 1:3=0.00639386 1:4=0.00000000 1:5=0.00584795 1:6=0.20040000 1:7=0.10030000 1:8=0.02300000
MT 245 1 1.000 107.0 1:2=0.02000000 1:3=0.05600000 1:4=0.00000000 1:5=0.00000000 1:6=0.00000000 1:7=0.02922158 1:8=0.12631579
MT 251 1 1.000 136.0 1:2=0.13384412 1:3=0.01738004 1:4=0.10528891 1:5=0.00070562 1:6=0.01081160 1:7=0.00697347 1:8=0.00453430
MT 264 1 1.000 207.0 1:2=0.00000000 1:3=0.00000000 1:4=0.00000000 1:5=0.00413223 1:6=0.00000000 1:7=0.00192377 1:8=0.00000000
MT 286 1 1.000 300.0 1:2=0.00157816 1:3=0.00126087 1:4=0.00124224 1:5=0.00144928 1:6=0.00209524 1:7=0.00124224 1:8=0.00197719
MT 292 1 1.000 337.0 1:2=0.02000000 1:3=0.30000000 1:4=0.04000000 1:5=0.00050000 1:6=0.00148588 1:7=0.00000000 1:8=0.04000000
MT 293 1 1.000 326.0 1:2=0.00000000 1:3=0.00000000 1:4=0.00000000 1:5=0.00000000 1:6=0.00153610 1:7=0.00113162 1:8=0.00000000
MT 295 1 1.000 333.0 1:2=0.00084409 1:3=0.00125321 1:4=0.00117912 1:5=0.00067806 1:6=0.00041798 1:7=0.00108578 1:8=0.00183284
MT 296 1 1.000 343.0 1:2=0.00000000 1:3=0.00000000 1:4=0.00000000 1:5=0.00233645 1:6=0.00000000 1:7=0.00108070 1:8=0.00144300

출력.txt

MT 233 1 1.000 60.0 1:2=0.10000000 1:3=0.00639386 1:4=0.00000000 1:5=0.00584795 1:6=0.20040000 1:7=0.10030000 1:8=0.02300000
MT 251 1 1.000 136.0 1:2=0.13384412 1:3=0.01738004 1:4=0.10528891 1:5=0.00070562 1:6=0.01081160 1:7=0.00697347 1:8=0.00453430
MT 286 1 1.000 300.0 1:2=0.00157816 1:3=0.00126087 1:4=0.00124224 1:5=0.00144928 1:6=0.00209524 1:7=0.00124224 1:8=0.00197719
MT 292 1 1.000 337.0 1:2=0.02000000 1:3=0.30000000 1:4=0.04000000 1:5=0.00050000 1:6=0.00148588 1:7=0.00000000 1:8=0.04000000
MT 295 1 1.000 333.0 1:2=0.00084409 1:3=0.00125321 1:4=0.00117912 1:5=0.00067806 1:6=0.00041798 1:7=0.00108578 1:8=0.00183284

=0.00000000열을 사용하여(열 5 이후) 행을 삭제하는 것이 훨씬 쉬울 수 있지만 grep -v "=0.00000000"이렇게 하면 너무 많은 데이터가 손실됩니다. 어떤 도움이라도 대단히 감사하겠습니다!

답변1

내가 찾을 수 있는 가장 간단한 해결책은 다음과 같습니다(예, 매우 간단합니다).

awk -F '=0\\.00000000'   'NF<=2'   file

이에 대한 몇 가지 가능한 해결책이 있습니다.

  1. grep텍스트를 찾는 것은 매우 빠르며 올바른 정규 표현식만 있으면 됩니다.

    grep -vE '^([^ ]* ){5}.*(=0\.00000000.*){2}' file
    
    • 이 부분은 ^([^ ]* ){5}행( )의 시작 부분부터 시작하여 공백(5 ( )개)으로 {5}구분된 열(공백 아님)과 일치합니다 ^.
    • 그런 다음 .*(=0\.00000000.*){2}해당 줄에서 최소한 두 개가 일치하게 됩니다 =0\.00000000.
    • 마지막으로 일치 항목을 반전하고( -v) 확장된(ERE) 정규식(덜 \필요함)을 사용합니다.

0일치하는 개수를 엄격하게 제한합니다.

  1. Sed에는 비슷한 정규 표현식이 있습니다.

    sed '/^\([^ ]* \)\{5\}.*\(=0\.00000000.*\)\{2\}/d' file
    

    그러나 패턴과 일치하지 않는 줄은 인쇄됩니다(쉽게 실패할 수 있음).

또는

  1. awk는 이 줄을 텍스트로 처리합니다.

    awk -F '=0\\.00000000' 'NF<=2' file
    
  2. awk는 부동 소수점 숫자를 구문 분석한 다음 0값을 확인할 수 있습니다.

    @GlennJackman의 답변을 사용하십시오.

답변2

공백이나 =필드 구분 기호를 사용하여 열 7부터 시작하여 0 값을 계산합니다. 값이 여러 개인 경우 다음 줄로 계속하고, 그렇지 않으면 해당 줄을 인쇄합니다.

awk -F '[= ]+' '{
    z = 0
    for (c = 7; c <= NF; c += 2)
        if ($c == 0.0 && ++z > 1)
            next
    print
}' file

답변3

이는 이 문자열의 여러 인스턴스를 포함하지 않는 줄을 인쇄하는 가장 간단한 방법입니다.

grep -v '=0\.00000000.*0\.00000000' file.txt

파일은 열 5 뒤에만 나타나며 한 번만 나타나거나 전혀 나타나지 않는 줄만 인쇄하려고 하므로 위 코드는 여러 번 나타나지 않는 줄을 인쇄합니다. 이 패턴은 어떤 열에 나타나는지에 관계없이 =0\.00000000.*0\.00000000한 줄의 두 인스턴스와 일치하며 , 한 줄의 어느 곳에든 세 번째, 네 번째, 다섯 번째 등이 있는 경우 해당 줄은 인쇄되지 않습니다. =0.00000000시도 중인 명령은 해당 문자열의 인스턴스가 포함되지 않은 줄을 인쇄하므로 원하지 않는 두 번째 줄은 인쇄되지 않습니다.

해당 문자열의 인스턴스가 더 이상 포함되지 않은 줄을 인쇄하려면 다른 인스턴스를 추가하세요 .*0.00000000. 예를 들어 인스턴스가 3개 이상 포함되지 않은 줄을 인쇄하려면 다음을 수행하세요.

grep -v '=0\.00000000.*0\.00000000.*0\.00000000' file.txt

여기에는 문자열의 세 인스턴스가 포함된 세 번째 줄이 포함됩니다.

관련 정보