나는 나만의 비밀번호 관리자를 작성 중이며 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
따라서 어느 정도 성공하고 항목이 변경됩니다(적어도 스트림에서는 있지만 실제로 파일을 변경하는 것은 그리 어렵지 않습니다).
그러나 두 가지 문제가 발생합니다.
출력에서 항목이 누락되었습니다. 그것이 바로
mastodon;password2
평화 입니다test;test
. 나는 그들이 a) 같은 줄에 머물고 b) 그대로 있기를 바랍니다.마지막 줄을 바꾸고 싶다면 항상 잘못된 것입니다. 예를 들어 이것을 사용하면
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
)을 인쇄합니다. 이런 식으로 레코드의 마지막 행도 성공적으로 변경했습니다.
admin
또한 조건을 정규식보다는 정확히 일치시키는 것이 현명한 것 같습니다. 한 계정 이름에 다른 계정 이름과 일치하는 문자열(예 : 및 의 문자열 webadmin
)이 포함될 수 있는지 알 수 없습니다.