先来了解 pcregrep 对比于 grep,来自 chatGPT
pcregrep
是一个强大的命令行工具,它使用 Perl 兼容的正则表达式 (PCRE) 来搜索文本。与标准的 grep
命令相比,pcregrep
提供了更多的正则表达式特性,允许用户执行更复杂和更灵活的文本匹配操作。这些特性包括但不限于更复杂的字符类、回溯引用、命名捕获组以及前后查找等。
-M 参数
-M
或 --multiline
参数允许 pcregrep
在多行模式下进行模式匹配。这意味着你可以使用一个正则表达式匹配跨越多行的模式。在不使用 -M
参数的情况下,pcregrep
(以及标准的 grep
)通常在单行模式下工作,每次只考虑输入中的一行。-M
参数允许正则表达式模式匹配操作涵盖输入中的连续多行,这在需要匹配或搜索跨多行展开的文本段落时非常有用。
pcregrep
与 grep
的区别
尽管 pcregrep
和标准的 grep
在很多基本用途上相似,主要区别在于它们支持的正则表达式的类型和复杂性:
正则表达式引擎:
grep
支持基本的正则表达式 (BREs) 和扩展的正则表达式 (EREs),而pcregrep
使用 PCRE 库,提供与 Perl 5 兼容的正则表达式。PCRE 提供了更多的正则表达式特性和更大的灵活性。性能和功能:由于
pcregrep
支持更复杂的正则表达式语法和构造,它能够执行一些标准grep
无法处理的匹配操作。例如,使用pcregrep
,你可以执行复杂的查找操作,如前后断言和条件子模式。多行匹配:如前所述,
pcregrep
的-M
参数允许跨多行进行模式匹配,这是标准grep
工具所不支持的。兼容性:
grep
几乎存在于所有 UNIX 和类 UNIX 系统中,是一个标准的命令行工具。而pcregrep
可能需要单独安装,尤其是在一些较旧或较小的系统中。
总之,尽管 pcregrep
在某些情况下提供了比标准 grep
更强大的功能,但它也可能需要用户对 Perl 兼容的正则表达式有更深入的了解。在选择使用哪个工具时,需要根据特定任务的需求和复杂性来决定。
使用 pcregrep 把file文件中的描文本提取出来存入到 newfile 文件中
pcregrep -M '(?s)<a .*?>(.*?)<\/a>' file >> newfile
pcregrep -M
表示对多行进行操作,(?s)
这是一个内联修饰符,它将正则表达式的模式设置为“单行模式”。在单行模式中,.
(点)匹配任何字符,包括换行符。这意味着正则表达式可以匹配跨越多行的模式。
<a .*?>
匹配开始的 标签。<a 是标签的开始,.*? 是一个非贪婪匹配,它匹配尽可能少的任何字符直到遇到 >,确保只匹配到单个 标签的开头部分。
(.*?)
这是一个非贪婪的捕获组,用于匹配 标签内的任意文本,直到遇到第一个 结束标签。
<\/a>
匹配结束的 标签。/ 是转义的 /,因为在正则表达式中 / 通常用作分隔符。
把每行开始的空白字符去掉(空格,tab,换行)
sed -i 's/^\s\+//g' newfile
这里^
表示行首, \s 表示空白字符(空格,tab,换行)+表示重复1次或多次空白字符, //表示替换为空,而后是 g 表示全局操作
删除每行的换行,除了后边的换行外
awk '/<\/a>$/ {print; next} {printf "%s", $0}' newfile > newfile2
这里源文件内容中,有的行中xxx是在一行,有的分成了三行,因此要处理成单行,因为 sed
是针对单行处理文本的。
这条 awk 命令检查 newfile 文件中的每一行,对于以 结尾的行,它将它们原样打印到 newfile2 文件中,并为每个这样的行添加换行符。对于其他行,它将它们连续输出到一行中,直到遇到一个以 结尾的行为止。
其中 /
同样表示分割字符, <\/a>$ 表示正则
,匹配以结尾的行,接着的 {print; next} 表示对正则匹配到的内容执行的操作,print; next
这里表示打印(print)当前行(因为不需要处理),而后直接跳到下一行执行操作(next), 接着的
{printf "%s", $0}
表示没有匹配到正则后的动作,printf 打印当前行 $0
, 直接拼接到上一行尾,而不添加其它操作。
因此如果多行都不是以结尾的话,它们会拼到一起,当然也可以添加一个空格进行分割,用 "%s "
即可。
提取锚文本部分存入到 newfile2
sed -i 's|<a [^>]*>\(.*\)</a>|\1|g' newfile2
这条 sed 命令设计用于在文本文件中查找和处理 HTML 标签,具体是删除这些标签本身,只保留标签内的文本内容。s 表示替换操作,注意这里使用|
作为分隔符,一般是使用 /
,但是如果要处理的字符串中有 / 这样的字符串,就要重新换一个。
<a [^>]*>
这里表示匹配 <a 一个空格,然后是[]字符组,字符组中的^表示非的意思,而不是开始的意思,即表示不是以>结尾的字符串,而后是 *
表示重复0或多次,然后是>, 因此这里表示<a ...>
表示<a
和 >
之间所有字符。而后是捕获组
.*表示任意字符, sed 中捕获组要使用 \(
和 \)
界定,接着又是|
分割符号,然后是 \1
表示引用的捕获组中的内容,即.*
表示的锚文本,整体来看 |\a|g 表示将匹配到的内容使用捕获组中的内容替换(全局模式)
去除文本中包含的和等标签
sed -i 's/<strong>//g; s/<\/strong>//g' newfile2
这里不用过多解释 //即替换为空 g参数表示全局,即把行内所有 strong 标签都替换, ; 分号用来分割另一条命令,替换的时候/要使用\转义下,即</strong>
去除每行行尾的空格
sed -i 's/[ \t]*$//' newfile2
-i
表示直接修改原文件, s 表示执行替换操作, []表示字符类,其中任意一个都会匹配 [ \t] 表示匹配空格或制表符, *表示0次或多次,$表示行尾 ,//表示替换为空字符, 如果 /t/则表示替换为字符 t
去除不包含任何字符或只包含空格的行
sed '/^ *$/d' newfile2 > file
这里 ^表示行的开始,然后是一个空格,后边的*表示空格重复0次或多次,然后是$表示行结束 /^ *$/
为正则表达式,后边的d 表示删除命令
注意 sed 是按行处理的,如果是多行,则 sed 就无能为力了
本文由 dealdot <dealdot#163.com> 创作, Full Stack Developer @ DeepBlue
本文最后编辑时间为: Mar 14, 2024 at 17:29 pm
转载请注明来源