Regex 用换行符/段落标记替换所有空白,以生成单词列表

Regex 用换行符/段落标记替换所有空白,以生成单词列表,regex,sed,Regex,Sed,我正试着为我们在课堂上翻译的一篇希腊文做主唱。我想用段落标记替换每个空格或制表符,以便每个单词都显示在自己的行中。谁能给我sed命令,解释一下我在做什么?我仍在试图弄清楚sed。对于相当现代的sed版本,编辑标准输入以生成标准输出 $ echo 'τέχνη βιβλίο γη κήπος' | sed -E -e 's/[[:blank:]]+/\n/g' τέχνη βιβλίο γη κήπος 如果您的词汇表单词位于名为lesson1和lesson2的文件中,请使用将sed的标准输出重

我正试着为我们在课堂上翻译的一篇希腊文做主唱。我想用段落标记替换每个空格或制表符,以便每个单词都显示在自己的行中。谁能给我sed命令,解释一下我在做什么?我仍在试图弄清楚sed。

对于相当现代的sed版本,编辑标准输入以生成标准输出

$ echo 'τέχνη βιβλίο γη κήπος' | sed -E -e 's/[[:blank:]]+/\n/g'
τέχνη
βιβλίο
γη
κήπος
如果您的词汇表单词位于名为
lesson1
lesson2
的文件中,请使用将sed的标准输出重定向到文件
all vocab

sed -E -e 's/[[:blank:]]+/\n/g' lesson1 lesson2 > all-vocab
这意味着什么:

  • 字符类
    [[:blank:]
    匹配单个空格字符或 单个制表符。
    • 使用
      [[:space:][]
      来匹配任何单个空白字符(通常是空格、制表符、换行符、回车符、换行符和垂直制表符)
    • +
      量词表示匹配一个或多个先前模式
    • 因此,
      [[:blank:][]+
      是一个由一个或多个字符组成的序列,这些字符都是空格或制表符
  • 替换中的
    \n
    是您想要的换行符
  • 末尾的
    /g
    修饰符意味着尽可能多地执行替换,而不是只执行一次
  • -E
    选项告诉sed使用POSIX扩展正则表达式语法,尤其是在这种情况下使用
    +
    量词。如果没有
    -E
    ,您的sed命令将变为
    sed-E的/[[:blank:]\+/\n/g'
    。(注意使用
    \+
    而不是简单的
    +
Perl兼容正则表达式 对于熟悉Perl兼容正则表达式和支持PCRE的sed的用户,请使用
\s+
匹配至少一个空格字符的运行,如中所示

sed -E -e 's/\s+/\n/g' old > new

这些命令从文件
old
读取输入,并将结果写入当前目录中名为
new
的文件

最大的便携性,最大的简陋性 追溯到几乎所有版本的sed,命令调用都有点巴洛克风格

$ echo 'τέχνη βιβλίο γη κήπος' | sed -e 's/[ \t][ \t]*/\
/g'
τέχνη
βιβλίο
γη
κήπος
注:

  • 在这里,我们甚至不假设谦逊的
    +
    量词的存在,并用一个空格或制表符(
    [\t]
    )后跟零个或多个(
    [\t]*
    )来模拟它
  • 类似地,假设sed不理解换行符的
    \n
    ,我们必须将其逐字包含在命令行中。
    • \
      和命令第一行的末尾是一个连续标记,它转义紧跟其后的换行符,命令的其余部分位于下一行。
      • 注意:转义换行前不得有空格。也就是说,第一行的结尾必须正好是反斜杠,后跟行的结尾
    • 这个容易出错的过程有助于理解为什么世界会移动到可见字符,并且在使用“复制和粘贴”尝试该命令时,您需要格外小心
关于反斜杠和引用的注释 以上所有命令都使用单引号(
“”
)而不是双引号(
“”
)。考虑:

$ echo '\\\\' "\\\\"
\\\\ \\

也就是说,与双引号字符串相比,shell对单引号字符串应用不同的转义规则。您通常希望使用单引号保护正则表达式中常见的所有反斜杠。

这应该可以完成以下工作:

sed -e 's/[ \t]+/\n/g'
[\t]
表示空格或选项卡。如果您想要任何类型的空间,也可以使用
\s

[\t]+
表示您想要多少空格或制表符(但至少一个)

s/x/y/
意味着将模式x替换为y(这里
\n
是一个新行)


结尾处的
g
意味着您必须重复每行中出现的次数。

可移植的方法是:

sed -e 's/[ \t][ \t]*/\
/g'
这是反斜杠和斜杠-g之间的一条实际新线。许多sed实现不知道
\n
,因此需要一个文字换行符。换行前的反斜杠可以防止sed对换行感到不安。(在sed脚本中,命令通常以换行符终止)

使用GNU sed,您可以在替换中使用
\n
,在正则表达式中使用\s:

sed -e 's/\s\s*/\n/g'
GNU sed还支持“扩展”正则表达式(即egrep样式,而不是perl样式),如果您给它-r标志,那么您可以使用
+

sed -r -e 's/\s+/\n/g'

如果这仅适用于Linux,您可能可以使用GNU命令,但如果您希望在使用非GNU sed(例如:BSD、Mac OS-X)的系统上使用此命令,则可能需要使用更便携的选项。

使用
gawk

gawk '{$1=$1}1' OFS="\n" file
  • 选择1

    echo $(cat testfile)
    
  • 选择2

    tr ' ' '\n' < testfile
    
    tr''\n'

  • 上面列出的所有sed break在一个或另一个平台上的示例。它们都不能与Mac上提供的sed版本兼容

    但是,Perl的正则表达式在任何安装了Perl的机器上都可以工作:

    perl -pe 's/\s+/\n/g' file.txt
    
    如果要保存输出,请执行以下操作:

    perl -pe 's/\s+/\n/g' file.txt > newfile.txt
    
    如果只希望出现唯一的单词:

    perl -pe 's/\s+/\n/g' file.txt | sort -u > newfile.txt
    

    您可以使用POSIX
    [[:blank:]
    来匹配水平空白字符

    sed 's/[[:blank:]]\+/\n/g' file
    
    或者您也可以使用
    [[:space:][]
    而不是
    [[:blank:][]

    示例:

    $ echo 'this  is a sentence' | sed 's/[[:blank:]]\+/\n/g'
    this
    is
    a
    sentence
    

    您也可以使用
    xargs

    cat old | xargs -n1 > new
    

    xargs-n1new
    
    至少在需要“sed-r-e…”确认的Linux下,可移植选项(即实际换行符)是在OpenBSD机器上识别换行符的唯一方法。已确认,可移植选项也是在macOS机器上识别换行符的唯一方法。这是有意义的,因为它们使用BSD sed。
    cat old | xargs -n1 > new
    
    xargs -n1 < old > new