csv 文件和 awk:如果第一列匹配,则更改第二列条目,然后打印完整文件

too*_*ley 2 awk text-processing posix

我正在编写自己的密码管理器,我希望它严格符合 POSIX 标准。为了简化:我有这个文件,file.csv

mastodon;password2
bla;test
test;test
posteo;tewtasdwqrr
Run Code Online (Sandbox Code Playgroud)

基本上,我想要一个带有两个参数的函数:它应该从第一列和该行中选择第一个参数,它应该用第二个参数替换第二列条目。

例如:f "bla" "etewtw"将最后一个条目的密码更改为etewtw.

我尝试使用 awk,它也有一定效果:

awk -F ";" -v acc="bla" -v newpw="etewtw" \
'$1 ~ acc { $2=newpw; print $1";"$2 } END {print;} ' file.csv
Run Code Online (Sandbox Code Playgroud)

基本上,newpw如果第一列与acc参数匹配,我尝试将第二列设置为参数。更改流后,我想打印完整的流,这不起作用。以上显然不是正确的解决方案,但我不知道如何解决。

输出是:

bla;etewtw
posteo;tewtasdwqrr
Run Code Online (Sandbox Code Playgroud)

所以还挺成功的,条目被改了(至少在流中,但实际上改文件并不困难)。

但是,会出现两个问题:

  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
Run Code Online (Sandbox Code Playgroud)

这不是我想要的。我希望最后一行与任何其他行没有什么不同。

Ed *_*ton 6

您需要其中任何一个才能将您的姓名和密码视为文字字符串:

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
Run Code Online (Sandbox Code Playgroud)

您需要这种方法,因为通过-v扩展转义序列传递的变量。因此,如果您传递的任何一个变量包含反斜杠,例如foo\tbar,那么\t中间的将被扩展并被视为文字制表符。

请参阅http://cfajohnson.com/shell/cus-faq-2.html#Q24和/或/sf/ask/1335297001/ -awk-script了解更多信息。