我在想如何替换sed -命令中的[^\]%
标记而不是标记\%
回答。我认为后视是没有必要的。
我当前的 Sed 命令,但我认为 Perl 在这里是必须的
cat something | sed 's#%.*</#</#'
这也删除了%
符号后面的所有内容,即 LaTeX 中的所有注释,但不删除百分比值。
我不成功的 Perl 尝试
cat something | perl 's#[^\]%.*</#</#'
我不知道如何让 Perl 获取 cat 的标准输出。
数据
------------------------------
Protocol of pre-eclampsia
------------------------------
Monitoring in 90\% cases
Antihypertensives when % this is a comment, please, remove me!
$SBP/DBP > 160/110$; slowly.
------------------------------
所需输出
------------------------------
Protocol of pre-eclampsia
------------------------------
Monitoring in 90\% cases
Antihypertensives when
$SBP/DBP > 160/110$; slowly.
------------------------------
你怎么可以替换%
标志而不呢\%
?如果您可以通过 Sed 做到这一点,请发表评论。
答案1
像许多(如果不是大多数)文本解析工具一样,perl
可以从命令行获取输入,因此不需要cat
.您只需要-e
它可以让您将脚本作为命令行参数传递,-n
这意味着“在每行输入上运行脚本”。或者,您可以使用-p
开关,这意味着“在每行输入上运行脚本,然后打印该行”。这两个命令是等效的(但第二个命令是 cat 的经典无用用法,请使用第一个):
perl -pe 's/foo/bar/' file
cat file | perl -pe 's/foo/bar/'
现在,如果我理解正确的话,您想要删除所有 LaTeX 注释(尽管这不是您的问题所述)。如果是这样,一个向后看是最简单的方法:
perl -pe 's/(?<!\\)%.*//' file
你的正则表达式也应该有效,你只需要保留在 之前匹配的字符%
并转义反斜杠:
perl -pe 's/(^|[^\\]+)%.*/$1/' file
你可以用 GNU 做同样的事情sed
:
sed -r 's/(^|[^\\])%.*/\1/' file
答案2
如果你只想替换后面的内容%
,而不是后面的内容\%
,在 Perl 中,最简单的方法是使用消极回顾%.*
:仅当前面没有反斜杠时才匹配。
perl -pe 's/(?<!\\)%.*//'
然而,这不会匹配类似的东西Hello world.\\%wibble
。为此,您需要检查 前面是否%
有偶数个反斜杠。你不能用lookbehind 来做到这一点,因为Perl 的lookbehind 只支持固定长度的模式。相反,匹配正则表达式中的反斜杠,并使用后向查找来确保正则表达式捕获所有反斜杠。
perl -pe 's/(?<!\\)((?:\\\\)*)%.*/$1/'
您也可以使用不支持lookbehind 的工具来做到这一点。在这种情况下,您需要使用一系列棘手的替换命令,或者匹配反斜杠并将它们复制到替换文本。
sed -e 's/^\(\(\\\\\)*\)%.*/\1/' -e 's/\([^\\]\(\\\\\)*\)%.*/\1/'
请注意,如果您正在处理 LaTeX 文档,则可能需要保留其他百分号,例如在逐字块中。仅使用正则表达式无法完成此操作。
答案3
替换未转义字符的常见习惯用法perl
是:
$ printf '%s\n' '% \% \\% \\\%' | perl -pe 's/(\\.)|%/$1||"<replacement>"/ge'
<replacement> \% \\<replacement> \\\%
因此,要删除从未转义开始的所有内容%
:
perl -pe 's/(\\.)|%.*/$1/g'
如果您sed
支持-E
(FreeBSD/GNU):
sed -E 's/(\\.)|%.*/\1/g'
或者使用 GNU sed
:
sed 's/\(\\.\)\|%.*/\1/g'
如果交替 RE 运算符不可用(如标准基本 RE 中),您通常可以使用\{0,1\}
:
sed 's/\(\(\(\\.\)\{0,1\}[^\\%]*\)*\)\(%.*\)\{0,1\}/\1/'