열 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
이에 대한 몇 가지 가능한 해결책이 있습니다.
grep
텍스트를 찾는 것은 매우 빠르며 올바른 정규 표현식만 있으면 됩니다.grep -vE '^([^ ]* ){5}.*(=0\.00000000.*){2}' file
- 이 부분은
^([^ ]* ){5}
행( )의 시작 부분부터 시작하여 공백(5 ( )개)으로{5}
구분된 열(공백 아님)과 일치합니다^
. - 그런 다음
.*(=0\.00000000.*){2}
해당 줄에서 최소한 두 개가 일치하게 됩니다=0\.00000000
. - 마지막으로 일치 항목을 반전하고(
-v
) 확장된(ERE) 정규식(덜\
필요함)을 사용합니다.
- 이 부분은
0
일치하는 개수를 엄격하게 제한합니다.
Sed에는 비슷한 정규 표현식이 있습니다.
sed '/^\([^ ]* \)\{5\}.*\(=0\.00000000.*\)\{2\}/d' file
그러나 패턴과 일치하지 않는 줄은 인쇄됩니다(쉽게 실패할 수 있음).
또는
awk는 이 줄을 텍스트로 처리합니다.
awk -F '=0\\.00000000' 'NF<=2' file
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
여기에는 문자열의 세 인스턴스가 포함된 세 번째 줄이 포함됩니다.