Regex 使用基于sed的反向引用的另一个字符串替换字符串
我正在尝试转换预定义的字符串Regex 使用基于sed的反向引用的另一个字符串替换字符串,regex,linux,sed,Regex,Linux,Sed,我正在尝试转换预定义的字符串%c#,其中可以是带有另一个字符串的某个数字。问题是另一个字符串的长度必须被截断为#字符数 理想情况下,这些命令集可以工作: FORMAT="%c10" LAST_COMMIT="5189e42b14797b1e36ffb7fc5657c7eea08f1c0f" echo $FORMAT | sed "s/%c\([0-9]\+\)/${LAST_COMMIT:0:\1}/g" 但显然\1上存在语法错误。您可以将其替换为一个数字,以查看我试图获得的输出 我愿意使用除
%c#
,其中
可以是带有另一个字符串的某个数字。问题是另一个字符串的长度必须被截断为#
字符数
理想情况下,这些命令集可以工作:
FORMAT="%c10"
LAST_COMMIT="5189e42b14797b1e36ffb7fc5657c7eea08f1c0f"
echo $FORMAT | sed "s/%c\([0-9]\+\)/${LAST_COMMIT:0:\1}/g"
但显然\1上存在语法错误。您可以将其替换为一个数字,以查看我试图获得的输出
我愿意使用除sed
之外的其他程序来实现这一点,但理想情况下,它应该是大多数linux安装都非常原生的程序
谢谢 这是我的想法
echo ${LAST_COMMIT} | head -c $(echo ${FORMAT} | sed -e 's/%c//')
使用sed
获取数字,并使用头获取第一个字符
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
这也是单行命令(内容相同,但太长太硬)
这是我的主意
echo ${LAST_COMMIT} | head -c $(echo ${FORMAT} | sed -e 's/%c//')
使用sed
获取数字,并使用头获取第一个字符
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
这也是单行命令(内容相同,但太长太硬)
$LAST_COMMIT
的值在运行sed
之前进行插值,因此还没有可返回的反向引用。GNUsed
中有一个/e
扩展,它支持类似的东西,但我只想使用一个功能稍强的工具
perl -e '$fmt = shift; $fmt=~ s/%c(\d+)/%.$1s/g; printf("$fmt\n", @ARGV)' '%c10' "$LAST_COMMIT"
当然,如果您可以放弃自己的特殊格式字符串说明符,并切换到与printf
兼容的格式字符串,只需直接使用printf
shell命令。在sed
运行之前插入$LAST\u COMMIT
的值,因此,目前还没有可供参考的反向参考。GNUsed
中有一个/e
扩展,它支持类似的东西,但我只想使用一个功能稍强的工具
perl -e '$fmt = shift; $fmt=~ s/%c(\d+)/%.$1s/g; printf("$fmt\n", @ARGV)' '%c10' "$LAST_COMMIT"
当然,如果您可以放弃自己的特殊格式字符串说明符,并切换到与printf
兼容的格式字符串,只需立即使用printf
shell命令。如果您可以更改格式字符串的格式,那么printf
可以是一个选项printf“%.10s”“5189e42b14797b1e36ffb7fc5657c7eea08f1c0f“
你想写一个漂亮的git日志输出吗?是的。好的,这个主意很有趣。我可以分两步来做。1.将%c替换为%。#s然后执行替换。其他人能一步到位吗?@nhahdh似乎无法让您的解决方案处理多个替换,即动态地将多个参数传递给printf。帮助?:)它适用于我printf“%.10s%.10s”“5189e42b14797b1e36ffb7fc5657c7eea08f1c0f”“abcdef5189e42b14797b1e36ffb7fc5657c7eea08f1c0f”
输出5189e42b14 abcdef5189
。不过,我并不完全确定平台的差异。如果您可以更改格式字符串的格式,那么printf
可以是一个选项printf“%.10s”“5189e42b14797b1e36ffb7fc5657c7eea08f1c0f”
您正在尝试编写一个漂亮的git日志输出吗?是的。好的,这个主意很有趣。我可以分两步来做。1.将%c替换为%。#s然后执行替换。其他人能一步到位吗?@nhahdh似乎无法让您的解决方案处理多个替换,即动态地将多个参数传递给printf。帮助?:)它适用于我printf“%.10s%.10s”“5189e42b14797b1e36ffb7fc5657c7eea08f1c0f”“abcdef5189e42b14797b1e36ffb7fc5657c7eea08f1c0f”
输出5189e42b14 abcdef5189
。不过,我并不完全确定平台的不同。只是想澄清一下。这将替换所有出现的%c
,还是只替换第一个?“全部”不是必需的,而是首选项。“s/%c/”将只删除第一个“%c”。因此,“s/%c([0-9]\+)/\1/”可能更好。我编辑了我的回答,注意到格式将是很多东西FORMAT=“%b-%t-%c10-%c5”
。其他的一切都会处理好,最终只剩下一个字符串,其中只有%c
,您需要哪个%cecho${FORMAT}sed-e的/^.*%c\([0-9]\+\)-%c\([0-9]\+\).$/\1/g'
将返回%c的第一个数字(即返回10)。和echo${FORMAT}sed-e的/^.*%c\([0-9]\+\)-%c\([0-9]\+\).$/\2/g'
将返回第二个数字%c(即返回5)。我的问题不同。给定LAST\u COMMIT=“asdfghjkl”
和FORMAT=“%c2-%c5”
代码应以asdfg
的形式返回。不必是一行,只是为了清楚。这将替换所有出现的%c
,还是只替换第一个?“全部”不是必需的,而是首选项。“s/%c/”将只删除第一个“%c”。因此,“s/%c([0-9]\+)/\1/”可能更好。我编辑了我的回答,注意到格式将是很多东西FORMAT=“%b-%t-%c10-%c5”
。其他的一切都会处理好,最终只剩下一个字符串,其中只有%c
,您需要哪个%cecho${FORMAT}sed-e的/^.*%c\([0-9]\+\)-%c\([0-9]\+\).$/\1/g'
将返回%c的第一个数字(即返回10)。和echo${FORMAT}sed-e的/^.*%c\([0-9]\+\)-%c\([0-9]\+\).$/\2/g'
将返回第二个数字%c(即返回5)。我的问题不同。给定LAST\u COMMIT=“asdfghjkl”
和FORMAT=“%c2-%c5”
代码应以asdfg
的形式返回。不必只有一行。您有一个语法错误-$(…)
和${…}
之间存在显著差异。此外,一般来说,在没有正确引用的情况下,不应使用echo
。最后,所有