일치하는 열에서 문자열을 바꾸는 방법은 무엇입니까?

일치하는 열에서 문자열을 바꾸는 방법은 무엇입니까?

이것이 파일이라고 가정

abc,def,ghi 
1,a,zeta
2,b,beta
3,c,ceta
4,d,xaq
5,gh,lpa

위는 예시일 뿐이고 실제로는 많은 열이 있으므로 헤더가 일치하는 열 문자열을 바꿔야 합니다(예: 헤더 이름 "def"를 NA로 변경). 예상 출력은 다음과 같습니다.

abc,def,ghi 
1,NA,zeta
2,NA,beta
3,NA,ceta
4,NA,xaq
5,NA,lpa

다음 명령을 사용하면 헤더 이름이 "def"인 열만 인쇄할 수 있습니다.

awk -F, 'NR==1{for(i=1;i<=NF;i++)if($i~/def/)f[n++]=i}{for(i=0;i<n;i++)printf"%s%s",i?" ":"",$f[i];print""}' /tmp/test

하지만 AWK만 사용하여 텍스트 파일의 모든 내용을 수정하고 인쇄할 수 있는 방법이 있습니까? 참고: 항상 두 번째 열인지는 확인되지 않았습니다.

답변1

사용 Miller:

$ mlr --csv put '$def = "NA"' file

를 사용하면 -I"그 자리에서" 변경이 이루어지며 터미널에 아무 것도 출력하지 않고 원본 파일을 수정합니다.

답변2

awk를 사용하십시오.

$ awk -v col='def' '
    BEGIN { FS=OFS="," }
    NR==1 { for (n=1; n<=NF; n++) if ($n == col) break }
    NR>1  { $n = "NA" }
    { print }
' file
abc,def,ghi
1,NA,zeta
2,NA,beta
3,NA,ceta
4,NA,xaq
5,NA,lpa

위의 내용은 열 이름이 일치한다고 가정하고, 방어 코드(예: NR>1 && n { $n = "NA" }.

NR>1 { $n = "NA" } { print }그런데, 변경하려는 대상 열만 인쇄하려면 { print $n }다음과 같이 하십시오.

$ awk -v col='def' -F, 'NR==1{for (n=1; n<=NF; n++) if ($n == col) break} {print $n}' file
def
a
b
c
d
gh

귀하의 질문에 있는 코드는 열을 인쇄하고 있습니다(읽기 쉽도록 공백을 추가했습니다).

awk -F, '
    NR==1 { for (i=1; i<=NF; i++) if ($i ~ /def/) f[n++]=i }
    { for (i=0; i<n; i++) printf "%s%s", i?" ":"", $f[i]; print"" }
'

사실 인쇄용으로많은 종류의포함하다 def이름이 지정된 열을 인쇄하는 대신 이름을 지정하십시오.정확히 def하지만 더 나은 코드는 다음과 같습니다.

awk -F, '
    NR==1 { for (i=1; i<=NF; i++) if ($i ~ /def/) f[++n]=i }
    { for (i=1; i<=n; i++) printf "%s%s", $(f[i]), (i<n ? OFS : ORS) }
'

" "해당 코드를 사용하면 OFS를 사용하고 원하는 값을 하드코딩하는 대신 f[]모든 awk 생성 배열 및 모든 수동 생성 배열처럼 배열이 0 대신 1에서 시작하므로 ORS에서는 그럴 필요가 없습니다. print마지막에 추가하세요.

답변3

col_num=$(awk -F "," '{for(i=1;i<=NF;i++){if ($i ~ /def/){print i }}}' content.txt)
awk -F "," -v col_num="$col_num"  'NR>1{$col_num="NA"}1' content.txt

output
abc,def,ghi
1 NA zeta
2 NA beta
3 NA ceta
4 NA xaq
5 NA lpa

관련 정보