열에서 일치하는 문자열 수를 기준으로 열을 제거합니다.

열에서 일치하는 문자열 수를 기준으로 열을 제거합니다.

열(행 수가 다른 열)에 =>${MaxAllowedNumberOfFs} 'F가 있는 경우 텍스트 파일의 모든 열을 삭제하려면 명령이 필요합니다.

가까운 의사코드가 있지만 일치 횟수 제한을 설정하는 방법을 모르겠습니다.

리미터가 3으로 설정되었다고 가정하면 입력 파일 예시는 다음과 같습니다.

F G F H H
G F F F A
F G F F F
F F F T F

그러면 원하는 출력은 다음과 같습니다.

G H H
F F A
G F F
F T F

의사코드 닫기(리미터는 파일에 따라 변경될 수 있고 변경될 수 있음):

MaxAllowedNumberOfFs="1012"

Count_of_columns=`awk '{print NF}' filename | sort -nr | sed -n '$p'` 

for((i=1;i<=$Count_of_columns;i++)); do awk -v i="$i" -v x="$MaxAllowedNumberOfFs" '$i == F =>x number of times {$i="";print $0}' filename; done

분명히 grep을 사용하여 모든 열을 반복하고 열에서 발생 횟수를 계산하고 기준을 충족하지 않는 열을 삭제할 수 있었습니다. 하지만 정말 느립니다. 정말 좋은 awk 명령을 원하지만 awk 기술이 없습니다.

답변1

한 가지 방법은 파일을 두 번 읽는 것입니다. 처음에는 F가 계산되고 두 번째에는 라인이 출력됩니다. 그처럼

#!/bin/sh

awk -v n=3 '
        NR==FNR { for (i=1;i<=NF;i++) { if ($i == "F") { c[i]++ }} ;next }                                                                            
        { for (i=1;i<=NF;i++) { if (c[i] < n) { printf("%s ", $i) } } ;printf("\n") }                                                                 

' filename filename

NR==FNR파일을 읽는 것이 이번이 처음인지 두 번째인지 구분하는 요령은 다음과 같습니다 . 이는 파일에 행이 있다고 가정하고 파일을 처음 읽을 때만 적용됩니다. 배열은 c열에 있는 F 문자 수의 개수입니다. next파일을 처음 읽을 때 이 행의 모든 ​​처리가 완료되었음을 나타냅니다 . 두 번째 줄은 파일을 두 번째로 읽을 때 실행됩니다.

답변2

이것은 설명이다조옮김 - 라인 필터 - 조옮김방법. 귀하의 (대용량 파일) 상황에는 적합하지 않을 수 있지만 다른 사람들에게는 가치가 있을 수 있습니다.

$ cat file
F G F H H
G F F F A
F G F F F
F F F T F

그 다음에

$ rs -T < file | perl -alne 'print unless (grep { $_ eq "F" } @F) > 3' | rs -T
F  G  H  H
G  F  F  A
F  G  F  F
F  F  T  F

답변3

아래 스크립트를 사용해보십시오. 훌륭하게 작동합니다.

for ((i=1;i<=5;i++)); do c=`awk -v i="$i" '{print $i}' o.txt|awk '$1=="F" {print $0}'| sed -n '/F/{;=;p}'| sed "N;s/\n/ /g"| sort -k1 -rn|sed -n '1p'| awk '{print $1}'`; if [[ $c -lt 3 ]]; then awk -v i="$i" '{print $i}' o.txt >file_$i; fi; done

paste  file_*

산출

G H H
F F A
G F F
F T F

관련 정보