使用sed(或awk)替换每行的前两个斜杠。

3

我有一个文本文件,从Asterisk数据库中保存下来的,看起来像这样:

/general/astbin                                   : /asterisk/bin
/general/astlang                                  : /var/lib/asterisk/sounds/za
/general/cdrdays                                  : 7
/general/cellc1                                   : _084[02-9]XXXXXX
/general/cellc2                                   : _0841.

我只想去掉每行的前两个正斜杠,并用空格替换它,但我无法解决。 使用sed -i 's/\// /g'会删除所有正斜杠,这不是我想要的。 有人有什么想法吗?
4个回答

3

小技巧:

sed -i -e 's|/| |' -e 's|/| |' inputfile

我认为你需要删除 g - Michael J. Barber
我认为你的意思是 sed -i -e 's|/| |' -e 's|/| |' - Ulrich Dangel
@mru,sed需要输入,无论是通过管道传输还是作为参数给出文件。 -i(如@stephen所示)隐含地指的是文件输入。 - ssapkota
@ssapkota 是的,我知道。我指的是你解决方案中额外的 g。 - Ulrich Dangel

3

以下是一次性完成的解决方案,与其他解决方案(*)相反:

sed -i 's,/\([^/]*\)/, \1 ,' file

(*) 除了Thaddee Tyl的问题,他的邮件是在我之前发送的,但很不幸一开始它不能工作。

为什么最好一次性完成?

因为这更合理,而且更有效率。

这里有个不太恰当的比喻。如果你在一个你没去过的图书馆里找两本Z作者的书,你不会在找到第一本后就离开图书馆,再进去继续找第二本,忽略了之前的尝试。

“证明”

# use tmpfs to conduct test in memory, avoiding disk I/O overhead
$ mkdir stupid-sed-speed-test
$ sudo mount -t tmpfs tmpfs stupid-sed-speed-test/ -o size=1050M
$ cd stupid-sed-speed-test/

# create 512 MB + "//\n" at the end
$ awk 'BEGIN{printf"%*s",512*1024**2,"";print"//";exit}' >file

# "forgetting" solution

$ time sed -e 's|/| |' -e 's|/| |' file >/dev/null 

real    0m4.817s
user    0m3.388s
sys     0m1.424s

$ time sed -i -e 's|/| |' -e 's|/| |' file 

real    0m5.450s
user    0m3.360s
sys     0m2.076s

# recreate 512 MB + "//\n" at the end
$ awk 'BEGIN{printf"%*s",512*1024**2,"";print"//";exit}' >file

# "one go" solution

$ time sed 's,/\([^/]*\)/, \1 ,' file >/dev/null

real    0m3.548s
user    0m2.080s
sys     0m1.464s

$ time sed -i 's,/\([^/]*\)/, \1 ,' file

real    0m4.155s
user    0m2.068s
sys     0m2.080s

如果你对我的硬件配置感兴趣,可以查看桌面电脑的详细信息。

虽然差异并不是惊人的,但25%有时候也是很大的差距。


@Stephen: 我觉得更新我的答案以更好地展示“一次性”解决方案和你接受的天真方案之间的差异会是一个好主意。 - przemoc
点赞为你的“理论”提供证据。科学万岁! - Marcin
@przemoc:感谢您的更新,尽管我尝试的解决方案如此之快,以至于我甚至没有注意到它 ;) - Stephen

1

代码应该可以正常工作:

sed -e 's/\// /' -e 's/\// /'

1
sed 不需要使用 / 作为分隔符,在这种情况下,使用 : 等字符会提高可读性。 - Vatine

0

这应该可以运行:

sed -i 's/^\/\([^\/]*\)\/ /\1 /'

你忘记了第二个空格。另外,使用任何字符都是错误的,因为模式匹配默认是贪婪的,所以它不起作用。 - przemoc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接