csv 파일 & awk: 첫 번째 열이 일치하면 두 번째 열 항목을 변경하고 나중에 전체 파일을 인쇄합니다.

csv 파일 & awk: 첫 번째 열이 일치하면 두 번째 열 항목을 변경하고 나중에 전체 파일을 인쇄합니다.

저는 POSIX를 엄격하게 준수하기 위해 나만의 비밀번호 관리자를 작성하고 있습니다. 단순화하려면 다음 파일이 있습니다 file.csv.

mastodon;password2
bla;test
test;test
posteo;tewtasdwqrr

기본적으로 저는 두 개의 인수를 취하는 함수를 갖고 싶습니다. 첫 번째 열에서 첫 번째 인수를 선택하고 해당 줄에서 두 번째 열 항목을 두 번째 인수로 바꿔야 합니다.

예를 들어: f "bla" "etewtw"마지막 항목의 비밀번호를 로 변경합니다 etewtw.

나는 awk를 사용하려고 시도했는데 어느 정도 작동합니다.

awk -F ";" -v acc="bla" -v newpw="etewtw" \
'$1 ~ acc { $2=newpw; print $1";"$2 } END {print;} ' file.csv

newpw기본적으로 첫 번째 열이 인수와 일치하면 두 번째 열을 인수로 설정하려고 했습니다 acc. 스트림을 변경한 후 전체 스트림을 인쇄하고 싶지만 작동하지 않습니다. 위의 내용은 분명히 올바른 해결책은 아니지만 이를 해결하는 방법을 모르겠습니다.

출력은 다음과 같습니다

bla;etewtw
posteo;tewtasdwqrr

그래서 그것은 다소 성공적이었습니다. 항목이 변경되었습니다(적어도 스트림에서는, 그러나 실제로 파일을 변경하는 것은 어렵지 않습니다).

그러나 두 가지 문제가 발생합니다.

  1. 출력에 항목이 누락되었습니다. 즉 mastodon;password2test;test. 나는 그것들이 a) 같은 줄에 머물고 b) 변하지 않을 것으로 기대합니다.

  2. 마지막 줄을 변경하고 싶다면 항상 잘못된 것입니다. 예를 들어 대신 사용하면 awk -F ";" -v acc="posteo" -v newpw="test" '$1 ~ acc { $2=newpw; print $1";"$2 } END {print;} '결과는 다음과 같습니다.

posteo;test
posteo test

그것은 내가 원하는 것이 아닙니다. 마지막 줄이 다른 줄과 다르지 않기를 바랍니다.

답변1

이름과 비밀번호를 리터럴 문자열로 처리하려면 다음 중 하나가 필요합니다.

acc='bla' newpw='etewtw' awk '
    BEGIN{FS=OFS=";"; acc=ENVIRON["acc"]; newpw=ENVIRON["newpw"]}
    $1 == acc{$2=newpw} 1
' file.csv

awk '
    BEGIN{FS=OFS=";"; acc=ARGV[1]; newpw=ARGV[2]; ARGV[1]=ARGV[2]=""}
    $1 == acc{$2=newpw} 1
' 'bla' 'etewtw' file.csv

-v변수가 확장 이스케이프 시퀀스 와 함께 전달되므로 이 접근 방식이 필요합니다 . 따라서 전달하는 변수 중 하나에 백슬래시가 포함되어 있으면(예: foo\tbar) \t중간에 있는 이 확장되어 리터럴 탭 문자로 처리됩니다.

보다http://cfajohnson.com/shell/cus-faq-2.html#Q24및/또는https://stackoverflow.com/questions/19075671/how-do-i-use-shell-variables-in-an-awk-script자세한 내용은.

답변2

내가 볼 수 있는 유일한 수정 사항은 섹션 print에 명령문 이 있지만 END일치하지 않는 행에 대한 명령문이 누락되었다는 것입니다. 대신에 당신이 해야 할 일은

awk -F';' -v OFS=';' -v acc='bla' -v newpw='etewtw' '$1 == acc {$2=newpw}1' file.csv

즉, 단순히 필드 Nr을 바꾸십시오. 2 새 비밀번호를 사용하고 일반적으로 (수정될 수 있는) 행을 인쇄합니다(이에 대한 간략한 표기법은 입니다 1). 이로써 마지막 줄의 기록을 바꾸는 데에도 성공했다.

또한 정규식 대신 조건을 정확히 일치시키는 것이 현명한 것처럼 보일 수 있습니다. 한 계정 이름에 다른 계정 이름과 일치하는 문자열이 포함될 수 있는지 알 수 없습니다(예: adminwebadmin).

관련 정보