次のCSVファイルがあります。
keyuat,carsim,logs-keyuat-carsim
lowuat,carsimserver,logs-lowuat-carsimserver
utils,dash,logs-utils-dash
utils,lifecycle,logs-utils-lifecycle
utils,lifecycle-nodejs,logs-utils-lifecycle-nodejs
workshop,cashier,logs-workshop-cashier
workshop,jfrog-dotnet,logs-workshop-jfrog-dotnet
workshop,labelsengine,logs-workshop-labelsengine
このCSVファイルに基づいて同時に実行する必要がある2つのコマンドを実行しようとしています。
oc project $1
oc patch dc $2 -p '{"metadata":{"labels":{"logentries":"$3"}}}'
上記の実際の例では、コマンドは次のようになります。
oc project keyuat
oc patch dc carsim -p '{"metadata":{"labels":{"logentries":"logs-keyuat-carsim"}}}'
awkを使用しようとしたが見えない特殊文字または/ r無効な文字関連の問題が引き続き見つかります。system
使用せずに代わりprint
に行の末尾に追加されるのではなく、一部の文字が行の先頭に重なっている場合:
awk -F , '{ cmd="oc project " $1 "\;" "\n" "oc patch dc " $2 " \-p '\''\{\"metadata\"\:\{\"labels\"\:\{\"logentries\"\:\"" $3"\""; print(cmd) }' ./csv/labels.csv
"}}}oject keyuat; oc patch dc carsim -p '{"metadata":{"labels":{"logentries":"logs-keyuat-carsim
"}}}oject lowuat; oc patch dc carsimserver -p '{"metadata":{"labels":{"logentries":"logs-keyuat-carsimserver
"}}}oject utils; oc patch dc dash -p '{"metadata":{"labels":{"logentries":"logs-utils-dash
awk -F , '{ cmd="oc project " $1 "\;" "oc patch dc " $2 " -p '\''\{\"metadata\"\:\{\"labels\"\:\{\"logentries\"\:\"" $3 "\"\}\}\}'\''"; system(cmd) }' ./csv/labels.csv
awk: cmd. line:1: warning: escape sequence `\;' treated as plain `;'
awk: cmd. line:1: warning: escape sequence `\{' treated as plain `{'
awk: cmd. line:1: warning: escape sequence `\:' treated as plain `:'
awk: cmd. line:1: warning: escape sequence `\}' treated as plain `}'
Already on project "keyuat" on server "https://test-ocp.exampleusage.eu:443".
Error from server (BadRequest): invalid character '\r' in string literal
Already on project "lowuat" on server "https://test-ocp.exampleusage.eu:443".
Error from server (BadRequest): invalid character '\r' in string literal
Now using project "utils" on server "https://test-ocp.exampleusage.eu:443".
Error from server (BadRequest): invalid character '\r' in string literal
このスクリプトをどのように変更できますか?
答え1
私は使用します
- ジャックJSON生成 - これは参照エッジケースを処理する最も安全な方法です。
- 強く打つビルドコマンド - 原因バッシュFAQ #50
json=$(jq -n -c --arg le "$3" '{metadata: {labels: {logentries: $le}}}')
# no `$` here, I'm building arrays
cmd1=(oc project "$1")
cmd2=(oc patch dc "$2" -p "$json")
# now, execute the commands
"${cmd1[@]}"
"${cmd2[@]}"
コマンドの内容を確認するには、次のようにします。
$ declare -p cmd1 cmd2
declare -a cmd1=([0]="oc" [1]="project" [2]="keyuat")
declare -a cmd2=([0]="oc" [1]="patch" [2]="dc" [3]="carsin" [4]="-p" [5]="{\"metadata\":{\"labels\":{\"logentries\":\"logs-keyuat-carsim\"}}}")
答え2
awkでは、単一引用符を簡単に印刷できます。\ 047
試してみることができます(ここに入力していますので、今はテストできません…正しいことを願っています!)
# if needed: take out "^M" from the input file
tr -d '\015' <inputfile.csv >inputfile_sanitized.csv
# then parse it with:
awk -F',' '
{ cmd1="oc project " $1
cmd2="oc patch dc " $2 " -p \047{\"metadata\":{\"labels\":{\"logentries\":\"" $3 "\"}}}\047"
## once sure: you can here do: system(cmd1 " ; " cmd2);
print cmd1 " ; " cmd2
}' inputfile_sanitized.csv
答え3
入力ファイルがUnixテキストファイルであり、関連するすべてのフィールドが「良好」であると仮定すると(挿入されたカンマ、引用符、または改行がなく、特別なJSONエンコーディングやシェルに追加の引用符は必要ありません)、次のことができます。単純なシェルループを使用して:
while IFS=, read -r project dc logentries; do
cat <<END_CMDS
oc project $project
oc patch dc $dc -p '{"metadata":{"labels":{"logentries":"$logentries"}}}'
END_CMDS
done <file | sh -s
これにより、コマンドストリームが生成されます。
oc project keyuat
oc patch dc carsim -p '{"metadata":{"labels":{"logentries":"logs-keyuat-carsim"}}}'
oc project lowuat
oc patch dc carsimserver -p '{"metadata":{"labels":{"logentries":"logs-lowuat-carsimserver"}}}'
(等)…sh -s
実行ステップに渡されます。
繰り返しますが、今日使用されているツールは、実際にCSVを解析する方法、シェルの文字列を引用する方法、およびJSONを作成する方法を知っています。
mlr --icsv -N --ojson cat file |
jq -r '
@sh "oc project \(."1")",
@sh "oc patch dc \(."2") \({metadata:{labels:{logentries:."3"}}}|tostring)"' |
sh -s
ここでは、mlr
(Miller)を使用して入力をCSVからデフォルトのJSON文書に変換します。その後、JSONドキュメントはJSONプロセッサによって解析されjq
、プロセッサは引用符付き文字列と適切な形式のJSONを含むシェルコードを生成します。以前のように出力を実行に送信しますsh -s
。
このような入力ラインの場合
"The ""Project""","A study, in many parts",It'll be fine
これにより、2つのコマンドが生成され、実行されます。
oc project 'The "Project"'
oc patch dc 'A study, in many parts' '{"metadata":{"labels":{"logentries":"It'\''ll be fine"}}}'