みんな。 ports.lstとmaster.tblという2つのファイルがあります。
ports.lstは次のようになります。
hawaii-P1
hawaii-P2
hawaii-P3
losangeles-P1
losangeles-P3
master.tblは次のようになります。
#Site 1 Honolulu
servername HAWAII-A hawaii-P1 InitFileA OutFileA otherfields
servername HAWAII-A hawaii-P2 InitFileA OutFileA otherfields
#servername HAWAII-A hawaii-P3 InitFileA OutFileA otherfields
servername HAWAII-A hawaii-P4 InitFileA OutFileA otherfields
#Site 16 Dallas
servername DALLAS-A dallas-P1 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P2 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P3 InitFileA OutFileA otherfields
#Site 8 L.A.
#servername LOSANGELES-A losangeles-P1 InitFileA OutFileA otherfields
servername LOSANGELES-A losangeles-P2 InitFileA OutFileA otherfields
#servername LOSANGELES-A losangeles-P3 InitFileA OutFileA otherfields
ports.lstにリストされているすべてのポートに対してmaster.tblファイルを検索し、ファイルが次のように「InitFileA」と「OutFileA」を置き換える必要があります。
#Site 1 Honolulu
servername HAWAII-A hawaii-P1 InitFileB-hawaii-username-ALPHA-password OutFileB-hawaii-username-ALPHA otherfields
servername HAWAII-A hawaii-P2 InitFileB-hawaii-username-ALPHA-password OutFileB-hawaii-username-ALPHA otherfields
#servername HAWAII-A hawaii-P3 InitFileB-hawaii-username-ALPHA-password OutFileB-hawaii-username-ALPHA otherfields
servername HAWAII-A hawaii-P4 InitFileA OutFileA otherfields
#Site 16 Dallas
servername DALLAS-A dallas-P1 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P2 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P3 InitFileA OutFileA otherfields
#Site 8 L.A.
#servername LOSANGELES-A losangeles-P1 InitFileB-losangeles-username-ALPHA-password OutFileB-losangeles-username-ALPHA otherfields
servername LOSANGELES-A losangeles-P2 InitFileA OutFileA otherfields
#servername LOSANGELES-A losangeles-P3 InitFileB-losangeles-username-ALPHA-password OutFileB-losangeles-username-ALPHA otherfields
それが私が今いるところですが、明らかに失敗しました。
awk 'NR==FNR{z[$0];next}{if ($3 in z && $4 == "InitFileA"){ c=(echo $3| awk -F '-' {print $1});$4="InitFileB-"c"-username-ALPHA-password";$5="OutFileB-"c"-username-ALPHA"}}1' ports.lst master.tbl > output.tbl
私も次のことを試しました。
awk 'NR==FNR{z[$0];next}{if ($3 in z && $4 == "InitFileA"){ c=$3; sub(/-.*/, "", $c);$4="InitFileB-"c"-username-ALPHA-password";$5="OutFileB-"c"-username-ALPHA"}}1' ports.lst master.tbl > output.tbl
私はこれについて心配してきました。ここで誰が私が間違っているかについての洞察を提供できますか?
ベストアンサー1
タスクを2つのラウンドに分割する正しい基本的なアイデアがありますが、awkルールでawkを呼び出します。ここでは読み取りを中止しました。このように単純な問題に対する解決策は複雑すぎる。
次のawkの部分を考えてみましょう。
awk 'BEGIN {
RS = "[\t\v\f ]*(\r\n|\n\r|\r|\n)";
FS = "[\t\v\f ]+"
}
FNR==1 {
file++
}
/^#/ {
next
}
file==1 {
port[$1] = $1
}
file>=2 && ($3 in port) {
base = $3;
sub(/-[^-]*$/, "", base);
$4 = "InitFileB-" base "-username-ALPHA-password";
$5 = "OutFileB-" base "-username-ALPHA";
}
file>=2 {
printf "%s\n", $0
} ' ports.lst master.tbl
注:上記のすべてを1行に書き込むために必要なセミコロンを追加しました。
サンプル入力ファイルを使用して上記のコードを実行すると、次のような結果が得られます。
losangeles-P1
losangeles-P3
servername HAWAII-A hawaii-P1 InitFileB-hawaii-username-ALPHA-password OutFileB-hawaii-username-ALPHA otherfields
servername HAWAII-A hawaii-P2 InitFileB-hawaii-username-ALPHA-password OutFileB-hawaii-username-ALPHA otherfields
servername HAWAII-A hawaii-P4 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P1 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P2 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P3 InitFileA OutFileA otherfields
servername LOSANGELES-A losangeles-P2 InitFileA OutFileA otherfields
このBEGIN
規則は、ファイルが異なる改行エンコードを使用する他のシステム(Windowsなど)から送信されている場合にのみ、汎用改行サポートを設定します。
このFNR==1
ルールは、file
処理中のファイルを反映するように変数を更新します(1番目は1、2番目は2)。
この/^#/ { next }
ルールは、ハッシュタグで始まるすべての行をスキップします。これはコメントであるため、保存する必要はありません。/^[\t\v\f ]*$/ { next }
出力ファイルを圧縮したい場合は、空白行をすべてスキップするルールを追加することもできます。
このfile == 1 { port[$1] = $1 }
ルールは、最初のファイルのすべての最初のフィールドを連想配列に追加しますport
。割り当てられた値(= $1
)は重要ではないので、= 0
ここで実際に使用できます。
ルールfile >= 2 && ($3 in port)
は2番目とそれ以降のファイルに適用され、3番目のフィールドが連想配列のキーの1つと一致する場合に実行されますport
。 (値は重要ではなくキーのみを確認します。)つまり、この規則は、3番目のフィールドがポートリストで指定されたキーの1つである場合にのみ適用されます。
3番目のフィールドは変数にコピーされますbase
。これはのキーの1つと一致し、port[]
最後のフィールド以降のすべてのエントリは-
を使用して削除されますsub()
。次に、4番目と5番目のフィールドを変更します。 awk には文字列連結演算子はありません。ただ文字列を合わせるだけです。つまり、「foo」、文字列に変換された変数値、「bar」("foo" a "bar")
で構成される文字列です。a
最後のルールは(変更可能な)レコードを印刷しますが、改行\n
文字を使用する必要があります。 2番目以降のファイルのレコードのみが使用されます。
ports.lst
各ユーザー名とパスワードを含めるように上記の内容(3行が変更されましたか?)を少し変更します。しかし、全体的なアプローチを見ることができることを願っています。