将所有空格替换为换行符/段落标记,形成一个单词列表

我正在尝试为我们在课堂上翻译的一篇希腊文本列出单词表。我想用段落标记替换每个空格或制表符,这样每个单词都会出现在它自己的行上。有没有人能给我一个 sed 命令,然后解释一下我在做什么?我还在想。

163899 次浏览

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

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

如果您的词汇表单词位于名为 lesson1lesson2的文件中,则将 sed 的标准输出重定向到具有

sed -E -e 's/[[:blank:]]+/\n/g' lesson1 lesson2 > all-vocab

意思:

  • 性格类 [[:blank:]]匹配单个空格字符或 一个制表符。
    • 使用 [[:space:]]代替匹配任何单个空白字符(通常是空格、制表符、换行符、回车符、表单馈送和垂直制表符)。
    • +量词表示 匹配一个或多个以前的模式
    • 所以 [[:blank:]]+是一个由一个或多个字符组成的序列,这些字符都是空格或制表符。
  • 替换中的 \n是您需要的换行符。
  • 最后的 /g修饰符意味着尽可能多地执行替换操作,而不是只执行一次。
  • -E选项告诉 sed 使用 POSIX 扩展的正则表达式语法,特别是在这种情况下使用 +量词。如果没有 -E,sed 命令就会变成 sed -e 's/[[:blank:]]\+/\n/g'。(请注意使用 \+而不是简单的 +。)

Perl 兼容正则表达式

对于那些熟悉兼容 Perl 的正则表达式和支持 PCRE 的 sed 的人来说,使用 \s+来匹配至少一个空白字符的运行,如

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

或者

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

这些命令读取来自文件 old的输入,并将结果写入工作目录中名为 new的文件。

最大限度的便携性,最大限度的暴躁

回到自 版本7 Unix以来的几乎所有 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,在 regex 中使用 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. 选择1

    echo $(cat testfile)
    
  2. Option 2

    tr ' ' '\n' < testfile
    

上面列出的所有在某个平台上使用 sed 中断的示例。它们都不能与 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 -n1 < old > new