我正在努力寻找一种方法来替换 *.tex 文件中的以下信息的所有行,例如:
text{fig/titel/Logo}text
到
text{fig/titel/Logo.png}text
我努力了:
egrep --include=*.tex -r ".*{fig/.*" *
它给了我想要进行更改的行。但是,例如,我该如何进一步使用 sed 命令呢?
我用过 find 和 sed,但从未使用过 grep 和 sed。有人可以帮忙吗?
答案1
假设GNU
工具(您似乎正在使用):
grep -r --include='*.tex' -lZ '{fig/.*}' . |
xargs -r0 sed -i.back 's:\({fig/[^}]*\)}:\1.png}:g'
grep
查找要更新的文件列表,sed
仅对这些文件进行更新。
或者,如果您只想添加.png
不存在的情况,GNUgrep
有一个-P
PCRE(?<!...)
正则表达式选项及其负向后查找运算符,但 GNUsed
还没有(尽管ssed
在同一个系列中),所以切换到perl
这里:
grep -Pr --include='*.tex' -lZ '\{fig/[^}]*(?<!\.png)\}' . |
xargs -r0 perl -pi.back -e 's:(\{fig/[^}]*(?<!\.png))\}:$1.png}:g'
使用 时-i.back
,原始文件将以扩展名保存.back
。
答案2
使用时sed
不需要grep
,因为sed
可以同时进行模式搜索。
在本例中,这是一个非常简单的表达式;查找字符串{fig/
,然后附加一个png
现在搜索表达式需要更聪明一点,因为我们想在结束}
字符处停止,但这很正常。我们还应该考虑到每行可能有多个。
所以我们最终得到
sed 's!{\(fig/[^}]*\)}!{\1.png}!g'
例如:
$ cat x
untouched lines
text{fig/titel/Logo}text
more lines
text{fig/somethingelse/image}text
text{fig/stuff}text and {fig/morestuff}text
$ sed 's!{\(fig/[^}]*\)}!{\1.png}!g' x
untouched lines
text{fig/titel/Logo.png}text
more lines
text{fig/somethingelse/image.png}text
text{fig/stuff.png}text and {fig/morestuff.png}text
我们可以看到条目{fig/...}
现在已png
附加,其他内容未受影响。