对于迁移过程,我需要在 bash 脚本中进行一些替换。
因此,在我的 .txt 文件中,我有以下引用:
[[File:My Image.png|400px|thumb|center|My Image]]
[[File:My Image.png|400px|thumb|center]]
[[File:My Image.png|400px|thumb]]
[[File:My Image.png|400px]]
[[File:My Image.png]]
我需要做的是将所有这些事件替换为这一行(仅 - 因此不再有大小、描述或其他信息):
[[File:My Image.png]]
因此,我尝试构建一个 PCRE 正则表达式来提取所有图像名称:
/File:(.*\..{3})/g
我构建了这个最终命令来查找 .txt 文件中的所有匹配项并使用正则表达式提取图像名称:
find . -name "*.txt" | xargs perl -i -p -e 's/File:(.*\..{3})/$1/g'
但是,我遇到了一些问题:
- 一个错误:
xargs:未终止的引号
- 最后我不知道如何使用提取的图像名称来替换所有出现的情况(完整的行)
PS:我在MacOS系统上使用bash v4
答案1
我写过一个新的正则表达式它与整体匹配[[...]]
,并仅用您想要保留的内容替换它。它假设文件名不包含管道|
字符或终止符]]
。我无法用 重现您的问题xargs
,但无论如何我都将其替换为find
s -exec
选项;以下内容对我在 Linux 上有效。
find . -name "*.txt" -exec perl -i -pe 's/(\[\[File:[^|]*).*?(\]\])/$1$2/g' '{}' +
答案2
尝试
find . -name '*.txt' -exec perl -i -pe 's/File:[^|]+\K\|[^]]+//g' {} \;
File:[^|]+
匹配File:
后跟非|
字符\K
这样我们就不必捕获前面的字符串并将其放回替换部分\|[^]]+
匹配|
后跟]
要删除的非字符- 也可以使用
sed -i '' 's/\(File:[^|]*\)|[^]]*/\1/g'
代替perl
进一步阅读:
- 为什么循环查找的输出是不好的做法?- 它有很多关于使用
find
命令的细节,包括选项的使用-exec
。 - 什么时候需要 xargs?