使用sed将段落转换为行

时间:2012-11-04 06:31:10

标签: unix sed

使用sed和任何基本命令,我试图计算每个单独段落中包含许多单独段落的单词数。每个段落以特定数字开头并增加。例如:

0:1.1这是第一段...

0:1.2这是第二段...

困难的是,每个段落都是一个包装而不是单行的段落。如果他们是单行,我可以计算每个段落中的单词。我该怎么做?感谢您的帮助

我确实想过如何计算每个段落:

grep'[0-9]:[0-9]'文件| wc -l <​​/ p>

4 个答案:

答案 0 :(得分:1)

awk解决方案可能适合您:

awk '/^[0-9]:[0-9]\.[0-9]/{ 
       if (pass_num) printf "%s, word count: %i\n", pass_num, word_count
       pass_num=$1
       word_count=-1
     }
     { word_count+=NF }
     END { printf "%s, word count: %i\n", pass_num, word_count }
    ' file

测试输入:

# cat file
0:1.1 I am le passage one.
There are many words in me.

0:1.2 I am le passage two.
One two three four five six
Seven

0:1.3 I am "Hello world"

测试输出:

0:1.1, word count: 11
0:1.2, word count: 12
0:1.3, word count: 4

<小时/> 工作原理:

每个单词由空格分隔,因此每个单词可以由awk中的每个字段表示,即一行中的字数等于NF。字数统计每行直到下一段。

当它遇到一个新的段落(由一个段落编号表示)时,它

  • 打印出上一段的数字和字数。
  • 将段号设置为此新段号
  • 重置段落字数(-1,因为我们不希望计算段号)

需要END{..}块,因为最后一段没有触发器,导致它打印出段号和字数。

if (pass_num)遇到第一段时,printf将取消awk

答案 1 :(得分:1)

这可能适合你(GNU sed):

sed -r ':a;$bb;N;/\n[0-9]+:[0-9]+\.[0-9]+/!s/\n/ /g;ta;:b;h;s/\n.*//;s/([0-9]+:[0-9]+\.[0-9]+)(.*)/echo "\1 = $(wc -w <<<"\2")"/ep;g;D' file

它将每个部分组成一行,然后计算部分中的单词减去部分编号(换行符替换为空格)。

答案 2 :(得分:0)

$ cat file
0:1.1 This is the first passage...
welcome to the SO, you leart a lot of things here.

0:1.2 This is the second passage...
wer qwerqrq            ewqr e
0:1.3 This is the second passage...

使用sed和GNU grep:

$ sed -n '/0:1.1/,/[0-9]:[0-9]\.[0-9]/{//!p}' file | grep -Eo '[[:alpha:]]*'   | wc -l
11

0:1.1 - &gt;在此处给出您想要计算的段落编号。

答案 3 :(得分:0)

这是GNU awk的一种方式:

awk -v RS='[0-9]+:[0-9]+\\.[0-9]+' -v FS='[ \t\n]+' 'NF > 0 { print R ": " NF - 2 } { R = RT }'

如果它在 doubledown 列出的文件上运行,则输出为:

0:1.1: 11
0:1.2: 12
0:1.3: 4

解释

这可以通过根据[0-9]+:[0-9]+\\.[0-9]+将输入拆分为记录并在空白处拆分为字段来实现。记录分隔符为1,因此{R = RT },字段计数器关闭2,因为每条记录以FS开头和结尾,因此NF - 2

编辑 - 仅计算包含[:alnum:]

的字段

以上也算如下省略号(...)作为单词,以避免这样做:

awk -v RS='[0-9]+:[0-9]+\\.[0-9]+' -v FS='[ \t\n]+' '
  NF > 0 { 
    wc = NF-2
    for(i=2; i<NF; i++)
      if($i !~ /[[:alnum:]]+/)
        wc--
    print R ": " wc
  } 
  { R = RT }'