进修如何应用 awk 的
!visited[$0]++
在不从头排序或转变原布列按次的条件下删掉反复的行。
假定你有一个文本文件,你必要删掉一切反复的行。
要维持本来的布列按次删掉反复行,运用:
这个剧本保护一个联系数组,索引(键)为文件中去重后的行,每一个索引对应的值为该行泛起的次数。对付文件的每一行,要是这行(以前)涌现的次数为 0,则值加 1,并打印这行,不然值加 1,不打印这行。
我以前不认识 awk
,我想弄清楚这么短小的一个剧本是怎样实现的。我调研了下,下面是调研心得:
!visited[$0]++
对输入文件的每一行都履行。visited[]
是一个联系数组(别名映照)范例的变量。awk
会在第一次履行时初始化它,是以咱们不需求初始化。$0
变量的值是当前正在被处置的行的内容。visited[$0]
经过与 $0
(正在被解决的行)相称的键来会见该映照中的值,即泛起次数(咱们在下面配置的)。!
对示意呈现次数的值取反:awk
中,随便非零的数或随便非空的字符串的值是 true
。visited[$0]
的值是一个比 0 大的数,取反后被剖析成 false
。visited[$0]
的值为即是 0 的数字或空字符串,取反后被剖析成 true
。++
表现变量 visited[$0]
的值加 1。awk
主动把它转换为 0
(数字) 后加 1。总的来说,全部表达式的意义是:
true
:要是示意涌现次数为 0 或空字符串false
:要是涌现的次数大于 0awk
由 形式或表达式和一个与之联系的行动 构成:
假如立室到了形式,就会履行背面的行动。若是省略行动,awk
默许会打印(print
)输入。
省略行动等价于
{print $0}
。
咱们的剧本由一个 awk
表达式语句构成,省略了行动。因而如许写:
即是如许写:
关于文件的每一行,假如表达式立室到了,这行内容被打印到输出。不然,不实行行动,不打印任何器材。
uniq
号令仅能对相邻的行去重。这是一个示例:
咱们也能够用下面的 sort 号令来摈除反复的行,可是本来的行递次没有被保存。
上面的要领会产出一个去重的文件,各行是基于内容举行排序的。经过管道联接下令能够处理这个题目。
事情道理
假定咱们有下面一个文件:
cat -n test.txt
在每行前面表现序号:
sort -uk2
基于第二列(k2
选项)举行排序,关于第二列沟通的值只保存一次(u
选项):
sort -nk1
基于第一列排序(k1
选项),把列的值作为数字来解决(-n
选项):
末了,cut -f2-
从第二列最先打印每一行,直到末了的内容(-f2-
选项:把稳 -
后缀,它示意这行背面的内容都蕴含在内)。
以上为全文。
【编辑保举】