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


126

我在一个小型工业包装盒中编写嵌入式Linux的Shell脚本。我有一个包含文本的变量pid: 1234,我想从行中删除前X个字符,因此仅保留1234。我需要“清理”更多变量,因此我需要删除X个第一个字符,${string:5}并且由于某些原因在我的系统中不起作用。

盒子里似乎唯一的东西是sed

我正在尝试使以下各项起作用:

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

有任何想法吗?


10
如果${string:5}不起作用,则说明您未使用Bash或其他支持该语法的shell。您使用什么外壳和版本?你的shebang长什么样?我的猜测是您正在使用sh(例如dash)或可能使用zsh
暂停,直到另行通知。

Answers:


0

这也可以完成工作:

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

27
该问题是“跳过字符串中的前N个字符”的第一击。您没有回答问题。
jww

这似乎并没有工作,如果这样做,你能解释一下如何
亚历山大·米尔斯

它确实可以在我的系统上运行。您的字段分隔符可能存在问题,请尝试awk -F": " '{print $2}'。仍然不是我最喜欢的解决方案。
mzuther

197

以下应该工作:

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

您确定bash外壳程序正在执行脚本吗?

即使符合POSIX

var=${var#?????}

最好使用外部过程,尽管这需要您以固定长度模式的形式对5进行硬编码。


1
您还可以使用第二个参数指定长度:${var:5:2}将从处开始1并返回12
Max Candocia

107

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

echo "$pid" | cut -c 5-

2
这是最简单的解决方案!
布兰登

2
从技术上讲,OP要求使用sed,但是我觉得这是“如何从[在终端/ bash中从字符串中删除前X个字符”的”最佳解决方案,当与git结合使用时,它很不错:git log --pretty=oneline | cut -c 42- | head
markiemers

1
+1简单而有用的解决方案..当我将URL设置为http:// <example.com>并剪切协议“ http://”时,我必须说成8个字符而不是7个字符。我不知道,但这就是它对我有用的方式。
Santosh Kumar Arjunan '18 -10-15

1
Santosh Kumar Arjunan:这是因为示例“ echo” $ pid“ | cut -c 4-”实际上不是剪切前4个字符,而是从第4个字符开始提取子字符串。因此,它实际上削减了前3个字符。因此,如果要剪切第7个字符,则要从第8个字符中提取所有内容,并因此执行“ cut -c 8-”
al-ash

1
@DeanHiller cut -c ${LEN}-。花括号用于将字符串与有效的变量字符连接起来,以区分变量是什么和变量不是。如果您想了解更多信息,请查阅“ bash变量字符串连接”以获取更多有关为什么/如何工作的资源。
JustCarty

46

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

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

1
如果我想从字符串中删除最后的X个字符,情况会怎样?
科凯什

5
@Kokesh:您可以sed -r 's/.{5}$//'改为删除最后5个字符
Mark Longair

7
如果逃脱了括号,则可以不使用-r-E在OS X中,IIRC中)(但是不知道在OS X中是否可行)。
暂停,直到另行通知。

2
@Dennis:我只是检查-逃离括号(和离开关-r/ -E)在OS X的作品
戈登戴维森

15

从字符串中剪切前两个字符:

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

@ dtp70非常感谢通用回答,它很棒!
wolfram77 '16

10

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

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

8

您也将有机会cut。如果是这样的话:

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

1
麻烦的cut是它不能合理地处理空白序列,tr -s ' '用来“压缩”空格会使它表现得更好。
雷神

1
这并不是要成为一种全能唱歌的舞蹈工具;它简单易行,就像罐子上所说的那样,并且广泛可用。它可以满足上述要求,并且肯定比从特定位置裁剪出固定字符更健壮。
肖恩·钦

5

那么,有这里已经解决方案sedawkcut以及使用bash的语法。我只想抛出另一个POSIX符合变量:

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

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


4

另一种方法,使用cut代替sed

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

他想删除前4个字符。这将获得前4个字符。
MM。

2

我在此问题提供的纯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

-i之后sed是编辑而不是文件(如果你想编辑文件之前,测试你的匹配表达式删除此开关)。

(我发布此消息是因为我想完全按照sed的要求执行此操作,而先前的回答均未解决该问题。)


1

与其从一开始删除n个字符,不如直接提取数字。像这样

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.