我想用 sed 模式匹配替换它的 ascii 十进制表示形式作为逗号分隔列表。将模式转换为 csv 整数字符串是在 bash 函数内完成的。该函数正在完成其工作,但我很难将其集成到 sed 调用中。这是示例代码:
#!/bin/bash
xx(){
##turns a string into its
##ascii-integer representation as a comma-separated list
##ignores double quotes at the start and end
n=0;o=""
for((k=1;k<$(echo $1 | wc -c);k++))
do
x=$(echo $1 | cut -b"$k")
a=$(printf '%d\n' "'$x" )
if [ $a = 34 ]
then
continue
else
n=$(($n+1))
if [ $n = 1 ]
then
o=$a
else
o=$(echo $o","$a)
fi
fi
done
o=$(echo '('$o')')
echo $o
}
##this works
xx "\"bla\""
##this does not work
y=$(echo "\"bla_x\"" | sed -e "s/bla/$(xx &)p")
该功能有效,但 sed 集成失败。通过谷歌搜索,我得到的印象是这原则上应该是可能的,所以可能只是一个小语法错误。
非常感谢任何帮助。
一切顺利
注意:在最终应用程序中,sed 的输入是一个带有 reg-exp 模式的文件(例如“k_[[:alnum:]]{5}”),该文件将被 csv 连接替换。所以最终“xx”必须从 sed 中调用。
答案1
仔细查看您的 sed 调用,它缺少 s/// 命令的结束斜杠。接下来,您使用双引号,因此即使在 sed 运行之前,由于双引号插值,s/// 命令的 rhs 已被填充。这不是你想要的。然而,这仍然无法让你越过球门柱。
/e
命令中有一个鲜为人知的标志GNU sed's s///
。这正是医生在本例中所要求的。它的作用是,根据运行 rhs 中给出的 shell 代码动态构造 s/// 命令的 rhs 并将其替换为其输出。注意:需要匹配整个模式空间。
这还要求导出您的用户定义函数以供子级使用。
#this does not work
##this is what YOU wrote
y=$(echo "\"bla_x\"" |
sed -e "s/bla/$(xx &)p")
##this now WORKS
export -f xx
y=$(
echo '"bla_x"' |
sed -Ee '
s/^.(.*)(_x).$/echo "$(xx '"\1"')\2"/e
'
)
echo "$y"
(98,108,97)_x
请注意 sed 命令中单引号的使用。
答案2
如果我理解正确,您可以使用以下方法简化您的功能printf
:
xx() {
# create an array to store every character of the word
declare -a arr
# loop the word to every char, removing quotes
for i in $(echo "${1//\"}" | grep -o .); do
# store the ascii value
arr+=($(printf "%d" "'$i"))
done
# create a variable with the values, comma separated
printf -v ascii "%s," "${arr[@]}"
# print the result adding the parenthesis and removing the last comma
echo "(${ascii%,})"
}
$ xx "\"bla\""
(98,108,97)
现在,xx
删除双引号,但在您的sed
命令中您尝试发送无引号模式(bla,而不是“bla”),因此如果您不希望它们出现在下一个代码的输出中,则必须将它们删除一些另一种方式:
p=bla
s="\"bla_x\""
c=$(xx "$p")
$ echo "$s" | sed "s/$p/$c/"
"(98,108,97)_x"