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)
所以还挺成功的,条目被改了(至少在流中,但实际上改文件并不困难)。
但是,会出现两个问题:
输出中缺少条目。即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
Run Code Online (Sandbox Code Playgroud)
这不是我想要的。我希望最后一行与任何其他行没有什么不同。
您需要其中任何一个才能将您的姓名和密码视为文字字符串:
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了解更多信息。