私は独自のパスワードマネージャを作成しており、POSIXと厳密に互換性があります。簡略化するには、次のファイルがありますfile.csv
。
mastodon;password2
bla;test
test;test
posteo;tewtasdwqrr
デフォルトでは、私は2つのパラメータを取る関数が欲しいです。最初の列で最初のパラメータを選択し、その行の2番目の列項目を2番目のパラメータに置き換える必要があります。
例: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
デフォルトでは、最初の列がパラメータと一致する場合は、2番目の列をパラメータに設定しようとしますacc
。ストリームを変更した後、ストリーム全体を印刷したいが機能しません。上記は明らかに正しい解決策ではありませんが、この問題を解決する方法がわかりません。
出力は次のとおりです
bla;etewtw
posteo;tewtasdwqrr
したがって、ある程度成功し、アイテムが変更されます(少なくともストリームではありますが、実際にファイルを変更することはそれほど難しくありません)。
しかし、2つの問題が発生します。
出力に項目がありません。それがまさに
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
)を含めることができるかどうかはわかりません。