我有一个相当有趣的问题,我不确定如何处理。我的文件看起来像这样:
GROUP1, 1 Tall.hat, 1 Bow.tie, 1 Shiny.shoe,
GROUP2, 1350 Red.apple, 1 Black.pencil, 1 Blue.pen, 1 Green.pen, 1 Little.tree,
GROUP30, 2 Green.bow, 4 Big.tree,
GROUP170, 1 Yellow.banana, 2 Green.apple, 1 Blue.skirt, 1 Purple.top, 1 Silver.shoe,
GROUP6, 2 Tall.hat, 2 Bow.tie, 2 Shiny.shoe,
GROUP7, 20 Red.apple, 20 Black.pencil, 20 Blue.pen, 20 Green.pen, 20 Little.tree,
每一行都包含一个包含项目的组,例如GROUP1包含1个Tall.hat,1个Bow.tie和1个Shiny.shoe。列以逗号分隔。我想删除每个项目只包含1个的行(或GROUP)。
期望的输出:
GROUP2, 1350 Red.apple, 1 Black.pencil, 1 Blue.pen, 1 Green.pen, 1 Little.tree,
GROUP30, 2 Green.bow, 4 Big.tree,
GROUP170, 1 Yellow.banana, 2 Green.apple, 1 Blue.skirt, 1 Purple.top, 1 Silver.shoe,
GROUP6, 2 Tall.hat, 2 Bow.tie, 2 Shiny.shoe,
GROUP7, 20 Red.apple, 20 Black.pencil, 20 Blue.pen, 20 Green.pen, 20 Little.tree,
因此GROUP1已被删除,因为它只包含每个项目中的1个。所有其他组至少有一个项目有两个或更多副本。
到目前为止的想法:
我需要忽略(但保留)column1,因为它包含组号。所以从awk -F "," 'NF>1'
开始。然后对于每一行,循环遍历所有列并记录找到的所有可能数字。例如,GROUP1 = 1; GROUP2 = 1350或1; GROUP30 = 2或4,GROUP170 = 1或2.如果找到唯一的唯一编号是1,则删除该行。
不确定如何实际实现这一点......任何想法都会很棒!
答案 0 :(得分:1)
这是使用awk的解决方案:
awk -F', *' '{
split("", counts) # empty the counts array at the start of each line
for (i = 2; i <= NF; ++i) { # loop through fields, starting from 2nd
split($i, a, /[. ]/) # split each field into parts
counts[a[3]] += a[1] # accumulate count for each type
if (counts[a[3]] > 1) { print; next } # print and skip to next line
}
}' file
-F', *'
将字段分隔符设置为逗号,后跟任意数量的空格。这使得事情变得容易一些,因为额外的空间被消耗掉,并且不会在以后的每个字段$2
,$3
中形成一部分。
counts
将包含“apple”,“pencil”,“pen”等键。对于每个键,值为总出现次数。
如果你为“Blue.pen”和“Green.pen”保留单独的计数,那么只需分成一个空格split($i, a, / /)
,而不是空格和点。现在,每个字段只会分为两部分,因此请在后续行中将a[3]
替换为a[2]
。
split
使用空字符串清除counts
数组是非GNU版本的awk的解决方法,可以用delete(counts)
替换。
答案 1 :(得分:0)
awk 解决方案:
awk -F", *" '{split($2,a," "); n=a[1]; for(i=3;i<NF;i++){ split($i,a," ");
if (a[1]!=n) { print; next} else {n=a[1]}} if(n!=1){ print } }' file
输出:
GROUP2, 1350 Red.apple, 1 Black.pencil, 1 Blue.pen, 1 Green.pen, 1 Little.tree,
GROUP30, 2 Green.bow, 4 Big.tree,
GROUP170, 1 Yellow.banana, 2 Green.apple, 1 Blue.skirt, 1 Purple.top, 1 Silver.shoe,
GROUP6, 2 Tall.hat, 2 Bow.tie, 2 Shiny.shoe,
GROUP7, 20 Red.apple, 20 Black.pencil, 20 Blue.pen, 20 Green.pen, 20 Little.tree,
详细:
split($2,a," ")
- 按空格拆分项目,以便a[1]
填充数字,a[2]
包含项目名称
n=a[1]
- 捕获每组中第一个项目的编号
for(i=3;i<NF;i++)
- 迭代剩余的项目
if (a[1]!=n) { print; next}
- 在第一种情况下,两个连续的项目编号不同 - 立即打破循环(跳转到next
行)并打印&#34;正确&#34 ;行
if(n!=1){ print }
- 如果该行中的所有项目编号没有差异(具有相同的值)且其值不等于1
- 打印该行,否则 - 该行赢了& #39;打印
答案 2 :(得分:0)
$ grep -E ' (1[0-9]|[2-9])' file
GROUP2, 1350 Red.apple, 1 Black.pencil, 1 Blue.pen, 1 Green.pen, 1 Little.tree,
GROUP30, 2 Green.bow, 4 Big.tree,
GROUP170, 1 Yellow.banana, 2 Green.apple, 1 Blue.skirt, 1 Purple.top, 1 Silver.shoe,
GROUP6, 2 Tall.hat, 2 Bow.tie, 2 Shiny.shoe,
GROUP7, 20 Red.apple, 20 Black.pencil, 20 Blue.pen, 20 Green.pen, 20 Little.tree,