我正在尝试编写一个sed
从字符串末尾删除 11 个数字字符的程序。这是我的代码...
fname="1a.out12345678901"
fname=$(echo "$fname"|sed 's/[0-9]{11}//')
但是,这只会设置fname
为1a.out12345678901
我将如何使用从字符串末尾sed
删除?12345678901
答案1
Bash 可以在不调用外部进程的情况下完成任务。
如果fname
以 11 个数字结尾,这将删除它们:
[[ $fname =~ (.*)[0-9]{11}$ ]] && fname=${BASH_REMATCH[1]}
笔记:
因为这种方法不需要创建子shell或外部进程,所以速度会更快。如果此任务在循环中完成,则速度可能很重要。
命令替换
$(...)
, 具有您可能不希望出现的副作用。例如,shell 从 of 命令替换中删除尾随换行符。这种方法不是 POSIX。它需要 bash。
例子
这说明了最后 11 位数字的删除:
$ fname="1a.out12345678901"; [[ $fname =~ (.*)[0-9]{11}$ ]] && fname=${BASH_REMATCH[1]}; echo "fname=$fname"
fname=1a.out
如果 fname 以超过 11 位数字结尾,则仅删除最后 11 位:
$ fname="1a.out012345678901"; [[ $fname =~ (.*)[0-9]{11}$ ]] && fname=${BASH_REMATCH[1]}; echo "fname=$fname"
fname=1a.out0
如果 fname 以少于 11 位数字结尾,则不会删除任何数字:
$ fname="1a.out1234567890"; [[ $fname =~ (.*)[0-9]{11}$ ]] && fname=${BASH_REMATCH[1]}; echo "fname=$fname"
fname=1a.out1234567890
答案2
一些东西:
- 您不使用 锚定到字符串的末尾
$
,因此这可能最终会删除其他地方的字符 {
仅在 ERE 模式下使用受支持的情况下才具有语法意义sed -r
,否则您需要\{
和\}
[0-9]
具有与区域设置相关的含义,为了保证您想要的行为,您应该设置一个符合您期望的区域设置(在本例中为C
)
将其放在一起:
$ echo 1a.out12345678901 | LC_ALL=C sed 's/[0-9]\{11\}$//'
1a.out
答案3
有几种简单的方法可以做到这一点。您可以使用 head、tail 或 cut,不需要 sed 或正则表达式:
通过使用头:
fname="1a.out12345678901"
fname=$(echo "$fname"|head -c -12)
head -c -N,它会剪切最后 N-1 个字符。尾巴也可以完成这项工作。
通过使用剪切:
fname="1a.out12345678901"
fname=$(echo "$fname"|rev |cut -c 12-|rev)
rev 将反转字符串
cut -c 12- 表示剪切前11个字符,从第12个字符开始。