如何使用awk删除标点符号?

时间:2018-02-08 05:10:54

标签: shell unix awk

我需要一个shell中的命令行,给出一个文本文件“novel”,每行显示一行,以及它对应的行数,将其写入一个名为“words”的文件中。问题是单词不能有标点符号。 这就是我所拥有的

$ awk '{for(i=1; i<=NF; ++i) {printf $i "\t" NR "\n", $0 > "words"}}' novel

该文件包含:

$ cat novel 
ver a don Quijote, y ellas le defendían la puerta:
-¿Qué quiere este mostrenco en esta casa?

预期产出:

ver 1
a 1
don 1
Quijote 1
...
puerta 1
Qué 2
...
casa 2

这是一个非常简单的学术用途。

2 个答案:

答案 0 :(得分:3)

使用awk

尝试此命令:

awk '{gsub(/[[:punct:]]/, "")} 1' RS='[[:space:]]' novel >words

例如,请考虑以下文件:

$ cat novel
It was a "dark" and stormy
night; the rain fell in torrents.

$ awk '{gsub(/[[:punct:]]/, "")} 1' RS='[[:space:]]' novel
It
was
a
dark
and
stormy
night
the
rain
fell
in
torrents

或者,要将输出保存在文件words中,请使用:

awk '{gsub(/[[:punct:]]/, "")} 1' RS='[[:space:]]' novel >words

工作原理:

  • gsub(/[[:punct:]]/, "")

    这告诉awk找到任何标点符号并用空字符串替换它。

    [:punct:]是一个包含所有标点符号的字符类。此表单包含unicode定义的所有标点符号。例如,Unicode定义了许多类型的引号字符。这将包括所有这些。

  • 1

    这是awk打印记录的简写。

  • RS='[[:space:]]'

    这告诉awk使用任何空白序列作为记录分隔符。这意味着每个单词定义一个单独的记录,awk将在一个单词中读取作为处理的时间。

计算单词

计算Unix中项目以使用sortuniq -c的常用方法如下:

$ echo 'one two two three three three' | awk '{gsub(/^[[:punct:]]|[[:punct:]]$/, "")} 1' RS='[[:space:]]' | sort | uniq -c
      1 one
      3 three
      2 two

或者,awk可以做到这一切:

$ echo 'one two two three three three' | awk '{gsub(/^[[:punct:]]|[[:punct:]]$/, ""); a[$0]++} END{for (w in a) print w,a[w]}' RS='[[:space:]]'
three 3
two 2
one 1

替代awk方法

Andriy Makukha表示我们可能不希望从I've中的单引号中删除标点符号。同样,我们可能不希望从网址中删除期间,以便google.com保持google.com。要仅在字符串的开头或结尾处删除标点符号时,我们会将gsub命令替换为:

gsub(/^[[:punct:]]|[[:punct:]]$/, "")

例如:

$ echo "I've got 'google.com'" | awk '{gsub(/^[[:punct:]]|[[:punct:]]$/, "")} 1' RS='[[:space:]]'
I've
got
google.com

使用sed

此sed命令将删除所有标点符号并将每个单词放在单独的行中:

sed 's/[[:punct:]]//g; s/[[:space:]]/\n/g' novel

如果我们对它运行命令,我们会得到:

$ sed 's/[[:punct:]]//g; s/[[:space:]]/\n/g' novel
It
was
a
dark
and
stormy
night
the
rain
fell
in
torrents

如果您想要保存在文件words中的字词,请尝试:

sed 's/[[:punct:]]//g; s/[[:space:]]/\n/g' novel >words

__工作原理:_

  • s/[[:punct:]]//g

    这告诉sed找到任何标点符号并将其替换为空。同样,我们使用[:punct:]因为它将处理所有unicode定义的标点字符。

  • s/[[:space:]]/\n/g

    这告诉sed找到任何空白序列并用一个换行符替换它。

答案 1 :(得分:0)

您可以使用awk的gsub功能

删除某些标点符号
awk '{ 
    gsub(/["*^&()#@$,\.!?~;]/,"")
    for(i=1; i<=NF; ++i) {print $i "\t" NR "\n" > "words"}
}' novel

您可以找到有关此功能的更多信息here

此外,您不需要使用printf $i "\t" NR "\n", $0,因为在大多数情况下,只会打印逗号之前的部分(格式)。因此,我将其更改为print,删除$0项。