使用bash提取字符串的多个部分

时间:2010-09-07 11:51:31

标签: bash

我有一个插入符号分隔(键=值)输入,并希望从中提取多个感兴趣的标记。

例如:给出以下输入

$ echo -e "1=A00^35=D^150=1^33=1\n1=B000^35=D^150=2^33=2"
1=A00^35=D^22=101^150=1^33=1
1=B000^35=D^22=101^150=2^33=2    

我想要以下输出

35=D^150=1^
35=D^150=2^

我试过以下

$ echo -e "1=A00^35=D^150=1^33=1\n1=B000^35=D^150=2^33=2"|egrep -o "35=[^/^]*\^|150=[^/^]*\^"
35=D^
150=1^
35=D^
150=2^

我的问题是egrep在一个单独的行上返回每个匹配。是否可以为一行输入获得一行输出?请注意,由于较大的脚本的限制,我不能简单地盲目替换输出中的所有\ n字符。

感谢您提出任何建议。此脚本适用于bash 3.2.25。任何egrep替代品都是受欢迎的。请注意,感兴趣的标记(35和150)可能会发生变化,我已经在脚本中生成了egrep模式。因此,一个班轮(如果可能的话)会很棒

3 个答案:

答案 0 :(得分:1)

您有两种选择。选项1是更改“空格字符”并使用set --

OFS=$IFS
IFS="^ "
set -- 1=A00^35=D^150=1^33=1  # No quotes here!!
IFS="$OFS"

现在,您的值已在$1$2

或者您可以使用数组:

tmp=$(echo "1=A00^35=D^150=1^33=1" | sed -e 's:\([0-9]\+\)=: [\1]=:g' -e 's:\^ : :g')
eval value=($tmp)
echo "35=${value[35]}^150=${value[150]}"

答案 1 :(得分:0)

要摆脱换行符,您可以再次回复它:

$ echo $(echo "1=A00^35=D^150=1^33=1"|egrep -o "35=[^/^]*\^|150=[^/^]*\^")
35=D^ 150=1^

如果这不满意(我认为它可能会为整个输入文件提供一行),您可以使用awk

pax> echo '
1=A00^35=D^150=1^33=1
1=a00^35=d^157=11^33=11
' | awk -vLIST=35,150 -F^ ' {
        sep = "";
        split (LIST, srch, ",");
        for (i = 1; i <= NF; i++) {
            for (idx in srch) {
                split ($i, arr, "=");
                if (arr[1] == srch[idx]) {
                    printf sep "" arr[1] "=" arr[2];
                    sep = "^";
                }
            }
        }
        if (sep != "") {
            print sep;
        }
    }'
35=D^150=1^
35=d^

pax> echo '
1=A00^35=D^150=1^33=1
1=a00^35=d^157=11^33=11
' | awk -vLIST=1,33 -F^ ' {
        sep = "";
        split (LIST, srch, ",");
        for (i = 1; i <= NF; i++) {
            for (idx in srch) {
                split ($i, arr, "=");
                if (arr[1] == srch[idx]) {
                    printf sep "" arr[1] "=" arr[2];
                    sep = "^";
                }
            }
        }
        if (sep != "") {
            print sep;
        }
    }'
1=A00^33=1^
1=a00^33=11^

这个允许您使用单个awk脚本,您需要做的就是提供以逗号分隔的键列表以便打印出来。


这是单行版本: - )

echo '1=A00^35=D^150=1^33=1
      1=a00^35=d^157=11^33=11
      ' | awk -vLST=1,33 -F^ '{s="";split(LST,k,",");for(i=1;i<=NF;i++){for(j in k){split($i,arr,"=");if(arr[1]==k[j]){printf s""arr[1]"="arr[2];s="^";}}}if(s!=""){print s;}}'

答案 2 :(得分:0)

给出包含字符串的'in'文件:

$ for i in $(cut -d^ -f2,3 < in);do echo $i^;done
35=D^150=1^
35=D^150=2^