使用sed删除字符串中的字符

使用sed删除字符串中的字符

我正在尝试编写一个sed从字符串末尾删除 11 个数字字符的程序。这是我的代码...

fname="1a.out12345678901"

fname=$(echo "$fname"|sed 's/[0-9]{11}//')

但是,这只会设置fname1a.out12345678901我将如何使用从字符串末尾sed删除?12345678901

答案1

Bash 可以在不调用外部进程的情况下完成任务。

如果fname以 11 个数字结尾,这将删除它们:

[[ $fname =~ (.*)[0-9]{11}$ ]] && fname=${BASH_REMATCH[1]}

笔记:

  1. 因为这种方法不需要创建子shell或外部进程,所以速度会更快。如果此任务在循环中完成,则速度可能很重要。

  2. 命令替换$(...), 具有您可能不希望出现的副作用。例如,shell 从 of 命令替换中删除尾随换行符。

  3. 这种方法不是 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

一些东西:

  1. 您不使用 锚定到字符串的末尾$,因此这可能最终会删除其他地方的字符
  2. {仅在 ERE 模式下使用受支持的情况下才具有语法意义sed -r,否则您需要\{\}
  3. [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个字符开始。

相关内容