这样做有一些问题。输出需要具有以下格式:在每一行上,首先打印一个单词,然后是冒号“:”,然后是空格,然后是单词出现的行号列表(用逗号分隔)。如果一个单词多次出现在一行中,它应该只报告该行的一次。
命令行:index.awk test1.txt> new.output.txt
我的代码(目前):
#!/bin/awk -f
Begin {lineCount=1} # start line count at 1
{
for (i = 1; i <= NF; i++) # loop through starting with postition 1
for ( j = 2; j <= NF; j++) # have something to compare
if ( $i == $j ) # see if they match
print $i ":" lineCount # if they do print the word and line number
lineCount++ # increment the line number
}
您会在示例输出中注意到它完全跳过输入文本文件的第一行。它从那里正确计算。如果多次出现,我该如何打印单词出现?同样,是否存在awk的原生函数,可以解释标点符号,数字,[],()等错误字符...
(编辑:gsub(regexp,replacement,target)可以从文本中省略这些错误字符。
示例INPUT:我想打印出每个单词,然后是 单词出现的相应行。我需要确定 打印出来时,我省略了字符串中的标点符号。如 好吧,我需要确保这个词在一行上出现不止一次 不要两次打印行号。
SAMPLE OUTPUT:
I:
would:
like:
to:
print:
out:
each:
word:
and,:
the:1
corresponding:
lines:
which:
the:
word:
occurs:
on.:
I:1
need:1
to:1
make:1
sure:1
.....ect (outputs the line numbers correctly from here)
答案 0 :(得分:3)
awk '{delete u;for (i=1;i<=NF;i++) u[$i]=1; for (i in u) cnt[i]=cnt[i]NR","} END{for (i in cnt) {sub(/,$/,"",cnt[i]); printf "%s: %s\n",i,cnt[i]}}' input
作为一个例子(文字比你的例子短一些):
$ cat file
I and I and I went
here and here and there
and then home
$ awk '{delete u;for (i=1;i<=NF;i++) u[$i]=1; for (i in u) cnt[i]=cnt[i]NR","} END{for (i in cnt) {sub(/,$/,"",cnt[i]); printf "%s: %s\n",i,cnt[i]}}' file
there: 2
went: 1
here: 2
and: 1,2,3
then: 3
I: 1
home: 3
该计划使用三个变量:i
,u
和cnt
。 u
用于在每行上创建唯一的单词列表。 cnt
用于跟踪每个单词的行号。 i
用作循环中的临时变量。
此代码使用awk
隐式循环遍历文件中每一行的事实。读取最后一行后,执行END
子句,显示结果。
依次考虑每个命令:
delete u
在每一行的开头,我们希望数组u
为空。
for (i=1;i<=NF;i++) u[$i]=1
在数组u
中为该行中的每个单词创建一个条目。
for (i in u) cnt[i]=cnt[i]NR","
对于该行中的每个单词,将当前行号添加到数组cnt
。
END{for (i in cnt) {sub(/,$/,"",cnt[i]); printf "%s: %s\n",i,cnt[i]}
处理完最后一行后,打印出数组cnt
中的每个条目。 cnt
中的每个条目都有一个额外的尾随逗号。使用sub
命令删除该逗号。然后printf
格式化输出。
假设我们想要忽略案例中的差异。为此,我们可以将所有单词转换为小写:
$0=tolower($0)
如果我们还想忽略标点符号,我们可以将其删除:
gsub(/[-.,"!?/]/," ")
全部放在一起:
awk '{delete u;$0=tolower($0);gsub(/[-.,"!?/]/," ");for (i=1;i<=NF;i++) u[$i]=1; for (i in u) cnt[i]=cnt[i]NR","} END{for (i in cnt) {sub(/,$/,"",cnt[i]); printf "%s: %s\n",i,cnt[i]}}' file