我正在編寫自己的密碼管理器,我希望它嚴格符合 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
例如)。