我正在尝试转换预定义字符串%c#
,其中#
可以是另一个字符串的某个数字。问题是,另一个字符串的长度必须截断为#
个字符。
理想情况下,这些命令集可行:
FORMAT="%c10"
LAST_COMMIT="5189e42b14797b1e36ffb7fc5657c7eea08f1c0f"
echo $FORMAT | sed "s/%c\([0-9]\+\)/${LAST_COMMIT:0:\1}/g"
但很明显\ 1上有语法错误。您可以用数字替换它以查看我想要输出的内容。
我愿意使用除sed
之外的其他程序来实现这一目标,但理想情况下它应该是大多数Linux安装本机的程序。
谢谢!
答案 0 :(得分:0)
这是我的想法。
echo ${LAST_COMMIT} | head -c $(echo ${FORMAT} | sed -e 's/%c//')
使用sed
获取号码,并使用head
获得第一个字符。
<强> EDIT1 强>
这可能会更好。
echo ${LAST_COMMIT} | head -c $(echo ${FORMAT} | sed -e 's/%c\([0-9]\+\)/\1/')
<强> EDIT2 强>
我制作剧本因为它太难理解了。请试试这个。
$ cat sample.sh
#!/bin/bash
FORMAT="%b-%t-%c10-%c5"
LAST_COMMIT="5189e42b14797b1e36ffb7fc5657c7eea08f1c0f"
## List numbers
lengths=$(echo ${FORMAT} | sed -e "s/%[^c]//g" -e "s/-//g" -e "s/%c/ /g")
## Substitute %cXX to first XX characters of LAST_COMMIT
for n in ${lengths}
do
to_str=$(echo ${LAST_COMMIT:0:${n}})
FORMAT=$(echo ${FORMAT} | sed "s/%c${length}/${to_str}/")
done
## Print result
echo ${FORMAT}
结果就是这样。
$ ./sample.sh
%b-%t-5189e42b1410-5189e5
这也是一行命令(内容相同但太长而且太难)
for n in $(echo ${FORMAT} | sed -e "s/%[^c]//g" -e "s/-//g" -e "s/%c/ /g"); do to_str=$(echo ${LAST_COMMIT:0:${n}}); FORMAT=$(echo ${FORMAT} | sed "s/%c${length}/${to_str}/"); done; echo ${FORMAT}
答案 1 :(得分:0)
length=$(echo $FORMAT | sed "s/%c\([0-9]\+\)/\1/g")
echo "${LAST_COMMIT:0:$length}"
答案 2 :(得分:0)
$LAST_COMMIT
的值在sed
运行之前进行插值,因此没有后向引用来引用。 GNU /e
中有一个sed
扩展名可以支持这样的内容,但我只是使用功能稍强的工具。
perl -e '$fmt = shift; $fmt=~ s/%c(\d+)/%.$1s/g; printf("$fmt\n", @ARGV)' '%c10' "$LAST_COMMIT"
当然,如果您可以放弃自己的ad-hoc格式字符串说明符,并完全切换到printf
兼容的格式字符串,只需直接使用printf
shell命令。 / p>