每个单词在一个单独的行上

时间:2012-11-20 21:59:26

标签: bash shell

我有一个像

这样的句子
  

这是例如

我想将此内容写入文件,以便将此句中的每个单词写入单独的行。

我如何在shell脚本中执行此操作?

7 个答案:

答案 0 :(得分:16)

有几种方法可以选择你最喜欢的方式!

echo "This is for example" | tr ' ' '\n' > example.txt

或者只是这样做是为了避免不必要地使用echo

tr ' ' '\n' <<< "This is for example" > example.txt

<<<表示法与herestring

一起使用

或者,使用sed代替tr

sed "s/ /\n/g" <<< "This is for example" > example.txt

还有更多选择,请查看其他人的答案=)

答案 1 :(得分:15)

$ echo "This is for example" | xargs -n1
This
is
for
example

答案 2 :(得分:9)

尝试使用:

string="This is for example"

printf '%s\n' $string > filename.txt

或利用 分词

string="This is for example"

for word in $string; do
    echo "$word"
done > filename.txt

答案 3 :(得分:5)

example="This is for example"
printf "%s\n" $example

答案 4 :(得分:2)

尝试使用:

str="This is for example"
echo -e ${str// /\\n} > file.out

输出

> cat file.out 
This
is
for
example

答案 5 :(得分:1)

N.B。我在简化正则表达式的一些草稿中编写了此代码,因此,如果有任何不一致之处,可能就是原因。

您关心标点符号吗?例如,在某些调用中,您会看到例如一个像(etc)这样的“单词”,正好带有括号。否则该词将是“括号”。而不是“括号”。如果您要使用适当的句子来解析文件,尤其是如果您想按单词排序甚至想要每个单词的单词计数,那么这可能是个问题。

有多种方法可以解决此问题,但有一些警告,当然还有改进的空间。这些恰好与数字,破折号(以数字表示)和小数点/点(以数字表示)有关。也许有一套精确的规则可以帮助解决这个问题,但是以下示例可以为您提供一些工作要做。我制作了一些人为的输入示例,以演示这些缺陷(或任何您想称呼它们的缺陷)。

$ echo "This is an example sentence with punctuation marks and digits i.e. , . ; \! 7 8 9" | grep -o -E '\<[A-Za-z0-9.]*\>'
This
is
an
example
sentence
with
punctuation
marks
and
digits
i.e
7
8
9

您可以看到 i.e。只是 i.e ,否则未显示标点符号。好的,但是这样可以省去诸如major.minor.revision-release之类的版本号之类的事情。 0.0.1-1 ;可以显示吗?是的:

$ echo "The current version is 0.0.1-1. The previous version was current from 2017-2018."|grep -o -E '\<[-A-Za-z0-9.]*\>'
The
current
version
is
0.0.1-1
The
previous
version
was
current
from
2017-2018

请注意,句子不以句号结尾。如果在年份和破折号之间添加空格,会发生什么?您不会破折号,但每年都会有自己的路线:

$ echo "2017 - 2018" | grep -o -E '\<[-A-Za-z0-9.]*\>'
2017
2018

问题就变成了是否要自己计算-;通过分隔单词的本质,如果有空格,则不会将年份作为单个字符串。因为这本身不是一个词,所以我认为不会。

我相信这些可以进一步简化。另外,如果您根本不需要任何标点符号或数字,可以将其更改为:

$ echo "The current version is 0.0.1-1. The previous version was current from 2017-2018."|grep -o -E '\<[A-Za-z]*\>'
The
current
version
is
The
previous
version
was
current
from

如果您想输入数字:

$ echo "The current version is 0.0.1-1. The previous version was current from 2017-2018."|grep -o -E '\<[A-Za-z0-9]*\>'
The
current
version
is
0
0
1
1
The
previous
version
was
current
from
2017
2018

至于带有字母和数字的“单词”,则可能是或可能不考虑的另一件事,但要证明上述内容:

$ echo "The current version is 0.0.1-1. test1."|grep -o -E '\<[A-Za-z0-9]*\>'
The
current
version
is
0
0
1
1
test1

输出它们。但是以下内容不会(因为它根本不考虑数字):

$ echo "The current version is 0.0.1-1. test1."|grep -o -E '\<[A-Za-z]*\>'
The
current
version
is

忽略标点符号很容易,但是在某些情况下可能需要或希望使用它们。在 eg 的情况下,我想您可以使用say sed将 eg 这样的行更改为 eg ,但这是个人喜好,我想

我只能总结一下它是如何工作的;我太累了,甚至考虑不多:

它如何工作?

我将仅说明调用grep -o -E '\<[-A-Za-z0-9.]*\>',但其他大多数调用都是相同的(扩展grep中的竖线/竖线符号允许使用多个模式):

-o 选项仅用于打印匹配项,而不是整行。 -E 用于扩展grep(也可以使用egrep)。至于正则表达式本身:

<\\>是单词边界(分别是开头和结尾-如果需要,您只能指定一个);我相信-w选项与同时指定两者相同,但是调用可能有所不同(我实际上不知道)。

'\<[-A-Za-z0-9.]*\>'说破折号,大小写字母和点零次或多次。至于为什么它将 eg 变成 .eg ,我现在只能说这是模式,但我没有能力再考虑它。

单词频率计数的奖励脚本

#!/bin/bash

if [ $# -eq 0 ]; then
    echo "Usage: $(basename ${0}) <FILE> [FILE...]"
    exit 1
fi

for file do
    if [ -e "${file}" ]
    then
        echo "** ${file}: "
        grep -o -E '\<[-A-Za-z0-9.]*\>' "${file}"|sort | uniq -c | sort -rn
    else
    echo >&2 "${1}: file not found"
    continue
    fi
done

示例:

$ cat example 
The current version is 0.0.1-1 but the previous version was non-existent.

This sentence contains an abbreviation i.e. e.g. (so actually two abbreviations).

This sentence has no numbers and no punctuation  
$ ./wordfreq example 
** example: 
   2 version
   2 sentence
   2 no
   2 This
   1 was
   1 two
   1 the
   1 so
   1 punctuation
   1 previous
   1 numbers
   1 non-existent
   1 is
   1 i.e
   1 has
   1 e.g
   1 current
   1 contains
   1 but
   1 and
   1 an
   1 actually
   1 abbreviations
   1 abbreviation
   1 The
   1 0.0.1-1

我没有将大写字母转译为小写字母,因此单词“ The”和“ the”显示为不同的单词。如果希望它们全部小写,可以在排序之前将脚本中的grep调用更改为通过管道传递给tr:

    grep -o -E '\<[-A-Za-z0-9.]*\>' "${file}"|tr '[A-Z]' '[a-z]'|sort | uniq -c | sort -rn

哦,由于您询问是否要将其写入文件,因此可以将其添加到 命令行(这是原始调用):

> output_file

对于脚本,您将像这样使用它:

$ ./wordfreq file1 file2 file3 > output_file

答案 6 :(得分:1)

使用fmt命令

>> echo "This is for example" | fmt -w1 > textfile.txt ; cat textfile.txt
This
is
for
example

有关fmt及其选项的完整说明,请查看related man page