文本文件的内容如下。
600466 a 37.50 25.28
600466 b 31.13 18.22
600466 c 64.80 61.39
600467 a 38.79 30.00
600467 b 28.73 41.04
600467 c 58.32 61.39
600468 a 33.09 25.28
600468 b 35.57 42.69
600468 c 58.32 60.12
600469 a 36.89 29.80
600469 b 35.57 30.94
600469 c 64.80 62.49
600470 b 37.35 35.02 *
600470 c 58.32 58.32 *
600471 a 29.22 25.47
600471 b 34.74 20.61
600471 c 64.80 62.81
600472 b 31.13 30.28*
600472 c 58.32 62.04 *
我用星号检查了一些行。
你可以让一行的第一个字段重复3次(所以它连续出现3次),但有些行不是。我想用一些shell命令删除那些行。
有没有人有想法?
(欢迎任何纠正我可怜的英语。谢谢你的提前)
答案 0 :(得分:2)
您可以使用以下awk
命令:
awk '++c[$1]<=3{m[$1]=m[$1]?m[$1]"\n"$0:$0}c[$1]==3{print m[$1]}c[$1]>3'
在多行而非优化版本中更好地解释:
example.awk:
{
# Count the occurences of $1
c[$1]++
}
c[$1]<=3{
# Append the current line to a temporary storage. If the
# temporary storage doesn't exist, create it.
m[$1]=m[$1]?m[$1]"\n"$0:$0
}
# Print the temporary storage once $1 has appeared 3 times
c[$1]==3{
printf "%s\n", m[$1]
}
# Print the current line if the count of $1 is above '3'
c[$1]>3
这样称呼:
awk -f example.awk input.txt
输出:
600466 a 37.50 25.28
600466 b 31.13 18.22
600466 c 64.80 61.39
600467 a 38.79 30.00
600467 b 28.73 41.04
600467 c 58.32 61.39
600468 a 33.09 25.28
600468 b 35.57 42.69
600468 c 58.32 60.12
600469 a 36.89 29.80
600469 b 35.57 30.94
600469 c 64.80 62.49
600471 a 29.22 25.47
600471 b 34.74 20.61
600471 c 64.80 62.81
答案 1 :(得分:2)
如果你的连续行不能连续超过3行,那么:
$ cat tst.awk
$1 != prev { buf=""; cnt=0 }
{ buf = buf $0 ORS; cnt++; prev=$1 }
cnt == 3 { printf "%s", buf }
否则:
$ cat tst.awk
($1 != prev) && (NR>1) {
if (cnt == 3) {
printf "%s", buf
}
buf = ""
cnt = 0
}
{ buf = buf $0 ORS; cnt++; prev=$1 }
END {
if (cnt == 3) {
printf "%s", buf
}
}
无论哪种方式:
$ awk -f tst.awk file
600466 a 37.50 25.28
600466 b 31.13 18.22
600466 c 64.80 61.39
600467 a 38.79 30.00
600467 b 28.73 41.04
600467 c 58.32 61.39
600468 a 33.09 25.28
600468 b 35.57 42.69
600468 c 58.32 60.12
600469 a 36.89 29.80
600469 b 35.57 30.94
600469 c 64.80 62.49
600471 a 29.22 25.47
600471 b 34.74 20.61
600471 c 64.80 62.81
答案 2 :(得分:1)
cut -d' ' -f1 file \
| uniq -c \
| grep -v ' 3 ' \
| rev | cut -d' ' -f1 | rev \
| grep -vwFf- file > output
第一行输出第一列。
第二行计算每个值出现的频率。
第三行排除了存在3次的那些行。
第四行删除了计数。
第五行从原始文件中排除字符串。
答案 3 :(得分:1)
我会说:
awk '$1 != prev_1 {if (a[prev_1]==3) print buffer; buffer=""}
{a[$1]++; buffer = (buffer?buffer ORS:"") $0}
{prev_1=$1}
END {if (a[$1]==3) print buffer}' file
也就是说,将缓冲区存储在变量buffer
中,并在第一个字段发生更改时打印它,以防它的计数器正好3
。
$ awk '$1 != prev_1 {if (a[prev_1]==3) print buffer; buffer=""} {a[$1]++; buffer = (buffer?buffer ORS:"") $0} {prev_1=$1} END {if (a[$1]==3) print buffer}' a
600466 a 37.50 25.28
600466 b 31.13 18.22
600466 c 64.80 61.39
600467 a 38.79 30.00
600467 b 28.73 41.04
600467 c 58.32 61.39
600468 a 33.09 25.28
600468 b 35.57 42.69
600468 c 58.32 60.12
600469 a 36.89 29.80
600469 b 35.57 30.94
600469 c 64.80 62.49
600471 a 29.22 25.47
600471 b 34.74 20.61
600471 c 64.80 62.81