AWK 从带有跳线的 CSV 文件中的项目启动操作系统命令

AWK 从带有跳线的 CSV 文件中的项目启动操作系统命令

我有一个 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 文件,我尝试运行两个必须同时运行的命令:

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=$(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 编码或 shell 中的额外引用),那么你可以这样做用一个简单的 shell 循环:

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、如何为 shell 引用字符串以及如何创建 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 的 shell 代码。像以前一样将输出发送到sh -s执行。

对于像这样的输入行

"The ""Project""","A study, in many parts",It'll be fine

这将生成并执行两个命令

oc project 'The "Project"'
oc patch dc 'A study, in many parts' '{"metadata":{"labels":{"logentries":"It'\''ll be fine"}}}'

相关内容