我有一个插入符号分隔(键=值)输入,并希望从中提取多个感兴趣的标记。
例如:给出以下输入
$ 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模式。因此,一个班轮(如果可能的话)会很棒
答案 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^