如何在仅包含ASCII字符的文件中搜索行,然后对其进行操作?

我有一个看起来像这样的文本文件:

English words only English and 日本語 日本語のみ English words only English and 日本語 日本語のみ English words only Also English words only English and 日本語 日本語のみ English words only English and 日本語 日本語のみ 

请注意,在中间有两行, English words only Also English words only ,一个接一个。

我需要做的是将这两行合并为一行,用/分隔,如下所示:

 English words only English and 日本語日本語のみEnglish words only English and 日本語日本語のみEnglish words only / Also English words only English and 日本語日本語のみEnglish words only English and 日本語日本語のみ 

我发现我可以使用以下正则表达式[[:ascii:]]搜索带有ASCII字符的行,并使用[^[:ascii:]]搜索非ASCII字符。 但是,我在使用正则表达式查找匹配条件的实例时遇到了一些麻烦,因为我需要搜索的是没有非ASCII字符的行。

我发现了关于“反向匹配”的问题 ,但是,我的答案超出了我的范围。

然后,当然,基于彼此之间的关系匹配线是另一个问题。 当它们一个接一个时,我可以匹配这些线吗? 我甚至不确定这是可能的。

有没有办法可以搜索没有非ASCII字符的所有行,然后使用LibreOffice,Gedit或命令行组合它们?

请注意,该文件长达数千行,我也不确定,但可能会出现仅包含3或4组的英文行。

看起来你可以使用sed来完成这项工作,即使它不知道[[:ascii:]]字符类。 [\d0-\d127] ,我们可以使用一系列转义序列 [\d0-\d127]指定所有ASCII字符,只要我们使用CPOSIX语言环境即可。

这是一个应该可靠的命令:

 LC_ALL=C sed -r ':a;N;s|^([\d0-\d127]+)\n([\d0-\d127]+)$|\1 / \2|;ta' file 

笔记

  • LC_ALL=C仅对此命令使用C语言环境设置(否则会出错)
  • -r使用扩展正则表达式使命令更具可读性(我们需要更少的反斜杠)(GNU sed也识别-E具有相同的含义)。
  • :a标签 – 循环从这里开始
  • ; 将命令分开,就像在shell中一样
  • N将下一行读入模式空间,以便我们可以替换\n
  • s|old|new|new替换old
  • ^([\d0-\d127])\n([\d0-\d127]+)$ – 匹配两行只有ASCII并捕获\1的第一行和\2的第二行。 ^是行的开头, \n是换行符, $是行尾,所以^line 1\nline 2$测试整line 1 line 2line 2
  • \1 / \2第一行和第二行,由/换行换行。
  • ta – 如果最后一个search-and-replace命令成功,则再次执行循环。 这允许我们处理文件的所有行,处理任何存在两个以上所有ASCII行的实例。

非常感谢Eliah Kagan 向我展示了如何使用转义序列来匹配ASCII字符 。

如果您想要整行只包含ASCII字符,则需要将模式锚定到行的起点和终点,例如使用grep

 $ grep -P '^[[:ascii:]]*$' file English words only English words only English words only Also English words only English words only 

有些工具提供了整行标志,例如grep的-x--line-regexp

  -x, --line-regexp Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing the pattern and then surrounding it with ^ and $. 

允许您使用:

 $ grep -Px '[[:ascii:]]*' file English words only English words only English words only Also English words only English words only 

多行匹配增加了另一层复杂性,因为许多常见的命令行文本处理实用程序都是基于行的。 您可以使用-Z标志强制grep覆盖整个文件,但是有一些工具如pcregrepperl本身可能更合适。

您需要解决的下一个问题是如何在多行匹配的上下文中解释“行首”和“行尾”的概念。 有些工具为其提供了标记,如Regex教程中所述:锚点 : perl是其中之一,它提供了一个/m修饰符。 您仍然需要通过-0777设置默认记录分隔符来-0777文件(在此处使用-0777完成); 例如

 $ perl -0777 -pe 's{^([[:ascii:]]+)\n([[:ascii:]]+)$}{$1 / $2}mg' file English words only English and 日本語日本語のみEnglish words only English and 日本語日本語のみEnglish words only / Also English words only English and 日本語日本語のみEnglish words only English and 日本語日本語のみ