shell 解析一行分隔字符串对并构造新命令

bgibtngc  于 2023-10-23  发布在  Shell
关注(0)|答案(2)|浏览(179)

我把这一行作为文件中的一行

show = "holder";  // [holder: Dispensor,dryer: Hair Dryer,bidet: Bedit,cover: Cover,wall mount: Wall Mount,screwdriver cutout: Screwdriver Cutout, assembly: Assembly,exploded: Exploded,vitamin: Vitamin]

我想要的是生成一个shell脚本文件,其中为每个xxx:yyy对生成以下行:

openscad --quite --export-format --D 'show=xxx' binstl -o xxx.stl $1

上面的$1是shell脚本的第一个参数。
我试过这个代码:

match($0, /\[[^\n\]]*\]$/) {                # get [xx:yy, aa:bb]
    s = substr($0, RSTART+1, RLENGTH-2);    # strip the [ and ]
    n = split(s, arr,",");                  # split the pairs
    for(x in arr) {                         # for each pair
        match(arr[x], /([^\n:]+)/, b) {     # get the first field of the pair
            print subsgtr(b[1], RSTART, RLENGTH)
        }
    }
}

结果是:

gawk: prog:5:       match(arr[x], /([^\n:]+)/, b) {     # get the first field of the pair
gawk: prog:5:                                     ^ syntax error

我也试过这个:

match($0, /\[[^\n\]]*\]$/) {                # get [xx:yy, aa:bb]
        s = substr($0, RSTART+1, RLENGTH-2);    # strip the [ and ]
        n = split(s, arr,",");                  # split the pairs
        for(x in arr) {                         # for each pair
            arr[x] ~ /([^\n:]+)/ print 
        }
    }

gawk: prog:5:       arr[x] ~ /([^\n:]+)/ print 
gawk: prog:5:                            ^ syntax error

还有这个

match($0, /\[[^\n\]]*\]$/) {                # get [xx:yy, aa:bb]
    s = substr($0, RSTART+1, RLENGTH-2);    # strip the [ and ]
    n = split(s, arr,",");                  # split the pairs
    for(x in arr) {                         # for each pair
        arr[x] ~ /([^\n:]+)/ { print }
    }
}

gawk: prog:5:       arr[x] ~ /([^\n:]+)/ { print }
gawk: prog:5:                            ^ syntax error

我不明白为什么我得到的语法错误。如果你给我一个不同的/更好的解决方案,如果可以的话,请解释语法错误,这样我就可以更多地了解awk。谢谢你,谢谢

nue99wik

nue99wik1#

awk模式操作语句表示为condition {action}。你不能在一个动作中使用相同的模式动作形式。使用if语句。例如,将arr[x] ~ /([^\n:]+)/ print替换为if(arr[x] ~ /([^\n:]+)/) print
对于您的问题,在给定的示例中,您可以将输入字段分隔符定义为正则表达式,并跳过第一个和最后一个字段。例如,与预期输出相比,添加了引号(因为您在那里有一些空格),并修复了2个错别字(quiet--export-format binstl):

$ cmd="openscad --quiet --export-format binstl --D 'show=X' -o 'X.stl' \"\$1\""
$ awk -F '[[:space:]]*(.*[[]|:[^,]*[],])[[:space:]]*' -v cmd="$cmd" '
  {for(i = 2; i < NF; i++) {c=cmd; gsub(/X/,$i,c); print c}}' file
openscad --quiet --export-format binstl --D 'show=holder' -o 'holder.stl' "$1"
openscad --quiet --export-format binstl --D 'show=dryer' -o 'dryer.stl' "$1"
openscad --quiet --export-format binstl --D 'show=bidet' -o 'bidet.stl' "$1"
openscad --quiet --export-format binstl --D 'show=cover' -o 'cover.stl' "$1"
openscad --quiet --export-format binstl --D 'show=wall mount' -o 'wall mount.stl' "$1"
openscad --quiet --export-format binstl --D 'show=screwdriver cutout' -o 'screwdriver cutout.stl' "$1"
openscad --quiet --export-format binstl --D 'show=assembly' -o 'assembly.stl' "$1"
openscad --quiet --export-format binstl --D 'show=exploded' -o 'exploded.stl' "$1"
openscad --quiet --export-format binstl --D 'show=vitamin' -o 'vitamin.stl' "$1"

注意:另一种方法是编写一个通用的bash脚本,在其中使用awk来提供一个循环。在下面的示例中,输入文件作为第二个参数($2)传递:

#!/usr/bin/env bash

if (( $# != 2 )); then
  printf 'usage: %s ARG FILE\n' "${0##*/}"
  exit 1
elif ! [[ -f "$2" ]]; then
  printf '%s: file not found\n' "$2"
  exit 1
fi
awk -F '[[:space:]]*(.*[[]|:[^,]*[],])[[:space:]]*' '
  {for(i = 2; i < NF; i++) print $i}' "$2" | while read -r s; do
  openscad --quiet --export-format binstl --D "show=$s" -o "$s.stl" "$1"
done
cunj1qz1

cunj1qz12#

这种方法会奏效吗?
示例数据:

cat test.txt
show = "holder";  // [holder: Dispensor,dryer: Hair Dryer,bidet: Bedit,cover: Cover,wall mount: Wall Mount,screwdriver cutout: Screwdriver Cutout, assembly: Assembly,exploded: Exploded,vitamin: Vitamin]

潜在解决方案:

awk 'BEGIN {
    FS = "[,:]"
}

{
    gsub(/^.*\[/, "", $1)
    for (i = 1; i <= NF; i += 2) {
        sub("^ ", "", $i)
        out = $i
        sub(" ", ".", out)
        print "openscad --quite --export-format --D \047show=" $i "\047 binstl -o " out ".stl \"$1\""
    }
}' test.txt
openscad --quite --export-format --D 'show=holder' binstl -o holder.stl "$1"
openscad --quite --export-format --D 'show=dryer' binstl -o dryer.stl "$1"
openscad --quite --export-format --D 'show=bidet' binstl -o bidet.stl "$1"
openscad --quite --export-format --D 'show=cover' binstl -o cover.stl "$1"
openscad --quite --export-format --D 'show=wall mount' binstl -o wall.mount.stl "$1"
openscad --quite --export-format --D 'show=screwdriver cutout' binstl -o screwdriver.cutout.stl "$1"
openscad --quite --export-format --D 'show=assembly' binstl -o assembly.stl "$1"
openscad --quite --export-format --D 'show=exploded' binstl -o exploded.stl "$1"
openscad --quite --export-format --D 'show=vitamin' binstl -o vitamin.stl "$1"

相关问题