如何使用 sed 从字符串中删除前 X 个字符?

Posted

技术标签:

【中文标题】如何使用 sed 从字符串中删除前 X 个字符?【英文标题】:How can I strip first X characters from string using sed? 【发布时间】:2012-07-13 06:35:52 【问题描述】:

我正在一个小型工业机器中为嵌入式 Linux 编写 shell 脚本。我有一个包含文本 pid: 1234 的变量,我想从该行中删除前 X 个字符,因此只保留 1234 个字符。我有更多变量需要“清理”,因此我需要删除 X 的第一个字符,而 $string:5 在我的系统中由于某种原因无法正常工作。

盒子里似乎只有sed

我正在尝试使以下工作:

result=$(echo "$pid" | sed 's/^.\4\//g')

有什么想法吗?

【问题讨论】:

如果 $string:5 不起作用,那么您没有使用 Bash 或其他支持该语法的 shell。您使用的是什么外壳和版本?你的shebang是什么样子的?我的猜测是您使用的是sh(例如dash)或者可能是zsh 【参考方案1】:

我在this question 提供的纯 sed 中找到了答案(诚然,在发布此问题后发布)。这完全符合您的要求,仅在 sed 中:

result=\`echo "$pid" | sed '/./  s/pid:\ //g; '\``

sed '/./) 中的点是您想要匹配的任何内容。您的问题正是我试图解决的问题,除了在我的情况下,我想匹配文件中的特定行然后取消注释。在我的情况下是:

# Uncomment a line (edit the file in-place):
sed -i '/#\ COMMENTED_LINE_TO_MATCH/  s/#\ //g; ' /path/to/target/file

sed 之后的-i 用于就地编辑文件(如果您想在编辑文件之前测试匹配的表达式,请删除此开关)。

(我发布这个是因为我想完全用 sed 来完成这个问题,而之前的回答都没有解决这个问题。)

【讨论】:

【参考方案2】:

这是使用cut(1) 剪切前X 个字符的简洁方法。此示例通过剪切从第 5 个字符开始的子字符串来删除前 4 个字符。

echo "$pid" | cut -c 5-

【讨论】:

从技术上讲,OP 要求使用 sed,但我觉得这是“如何从字符串 [in a terminal/bash] 中删除前 X 个字符”与 git 结合使用时的最佳解决方案,很好:git log --pretty=oneline | cut -c 42- | head +1 简单而有用的解决方案.. 当我的 URL 为 http:// 并削减协议“http://”时,我不得不改为 8 个字符7。我不知道,但这就是它对我的工作方式。 Santosh Kumar Arjunan:那是因为示例 "echo "$pid" | cut -c 4-" 实际上没有剪切前 4 个字符,而是从第 4 个字符开始提取子字符串。因此它实际上削减了前 3 个字符。因此,如果要剪切 7 个第一个字符,则要从第 8 个字符中提取所有内容,因此确实要执行 "cut -c 8-" 我该如何做 cut -c $LEN- 这样我可以传递变量中的金额? @DeanHiller cut -c $LEN-。花括号用于将字符串与有效的变量字符连接起来,以区分什么是变量,什么不是。如果您想了解更多信息,请查看“bash 变量字符串连接”以获取有关其工作原理/方式的更多资源。【参考方案3】:

从字符串中删除前两个字符:

$ string="1234567890"; echo "$string:2"
34567890

【讨论】:

@dtp70 非常感谢一个通用的答案,效果很好!【参考方案4】:

嗯,这里有sedawkcut 和使用bash 语法的解决方案。我只想加入另一个符合 POSIX 的变体:

$ echo "pid: 1234" | tail -c +6
1234

-c 告诉tail 从哪个字节偏移开始,从输入数据的末尾开始计数,但是如果数字以+ 符号开头,则它是从输入数据的开头到结尾。

【讨论】:

我真的很喜欢这个答案,因为它完全满足 OP 的要求,而无需使用过于复杂的工具。【参考方案5】:

也许您可以直接提取数字,而不是从一开始就删除 n 个字符。就这样……

$ echo "pid: 1234" | grep -Po "\d+"

这可能是一个更强大的解决方案,并且看起来更直观。

【讨论】:

【参考方案6】:

以下应该有效:

var="pid: 1234"
var=$var:5

您确定bash 是执行您的脚本的shell 吗?

即使是符合 POSIX 标准的

var=$var#?????

会比使用外部进程更可取,尽管这需要您以固定长度模式的形式对 5 进行硬编码。

【讨论】:

您还可以使用第二个参数指定长度:$var:5:2 将从1 开始并返回12【参考方案7】:

另一种方式,使用cut 而不是sed

result=`echo $pid | cut -c 5-`

【讨论】:

他想删除前 4 个字符。这将获取前 4 个字符。【参考方案8】:

通过awk 'print substr($0,42)' 传递它,其中 42 比要删除的字符数多一。例如:

$ echo abcde| awk 'print substr($0,2)'
bcde
$

【讨论】:

【参考方案9】:

很有可能,您也会拥有cut。如果是这样:

[me@home]$ echo "pid: 1234" | cut -d" " -f2
1234

【讨论】:

cut 的问题在于它不能明智地处理空白序列,使用tr -s ' ' 来“挤压”空格使其表现更好。 它不是一个会唱歌跳舞的工具;它很简单,正如它在罐头上所说的那样,并且可以广泛使用。它应该可以很好地满足上述要求,并且肯定比从特定位置裁剪固定字符更健壮。【参考方案10】:

sed 使用-r 选项(“在脚本中使用扩展的正则表达式”)以使用n 语法:

$ echo 'pid: 1234'| sed -r 's/^.5//'
1234

【讨论】:

如果我想从字符串中删除最后 X 个字符,情况会怎样? @Kokesh: 你可以用sed -r 's/.5$//' 去掉最后 5 个字符 如果你转义大括号,你可以不使用-r(OS X 中的-E,IIRC)(但不知道这是否适用于 OS X)。【参考方案11】:

这也可以完成这项工作:

echo "$pid"|awk 'print $2'

【讨论】:

这个问题是“跳过字符串中的前 N ​​个字符”的第一个问题。你没有回答问题。 这似乎行不通,如果行,你能解释一下如何 它在我的系统上运行。您的字段分隔符可能有问题,请尝试awk -F": " 'print $2'。不过,这不是我最喜欢的解决方案。

以上是关于如何使用 sed 从字符串中删除前 X 个字符?的主要内容,如果未能解决你的问题,请参考以下文章

如何从sed输出中删除不可见字符到文件[重复]

如何从字符串中删除前 10 个字符?

关于linux的sed用法。如何替换特殊字符,如IP=192.168.0.1替换成IP=117.112.3.8

如何从字符串中删除特殊字符?

使用 sed 从字符串中删除单斜杠而不是双斜杠

使用 sed 从字符串中删除子字符串