我有一个奇怪的项目
我有很长的档案。它的分隔列由' |'共有8个。 第8列。已列出浏览器(chrome,I.E,safari等)。 我需要按字母顺序打印它们,然后 每个用户打印它们。 例如:Chrome 432
Safari 543
etc..
到目前为止我已经尝试了
grep -v "^#" < < file > | awk -F '|' '{ print $8 }' | sort | uniq -c
grep
删除所有#
条评论
awk
获取第8列
然后sort
和uniq
来打印&#39;结果
这就是我得到的:
2
2307 Internet Explorer
369 Safari
2785 Chrome
316 Opera
4182 Firefox
所以我首先需要摆脱那种无关紧要的&#39; 2&#39;在开始(我认为它必须是空白或其他)
脚本必须是&#34;通用&#34;所以我不能使用grep -c "Chrome"
例如
如果我尝试在awk
之后运行另一个uniq
,结果会变得非常混乱
2
2785
4182x
2307net Explorer
316
369i
最后它似乎是第9列,因为&#34; Internet Explorer&#34;我怎样才能将它与第8列合并?
p.s我最大的问题是先获得名字,然后再获得麻烦
p.s 2我检查了这个帖子frequency count for file column in bash,我无法得到我想要的结果
我的文件的比例
#id|lastName|firstName|gender|birthday|creationDate|locationIP|browserUsed
1099511633435|Smith|Jack|male|1981-04-19|2010-05-26T03:45:11.772+0000|50.72.193.218|Internet Explorer
1099511635042|Kiss|Gyorgy|male|1984-09-14|2010-05-16T22:57:41.808+0000|91.137.244.86|Chrome
1099511635218|Law-Yone|Eric|male|1987-01-20|2010-05-26T20:10:22.515+0000|203.81.95.235|Chrome
1099511638444|Jasani|Chris|female|1981-05-22|2010-04-29T20:50:40.375+0000|196.223.11.62|Firefox
2199023256615|Arbelaez|Gustavo|male|1986-11-02|2010-07-17T18:53:47.633+0000|190.96.218.101|Chrome
答案 0 :(得分:0)
尝试:
grep -v "^#" file | awk -F'|' '{print$8}' | sort | uniq -c | awk '{print$2,$3,$1}'
答案 1 :(得分:0)
你已经完成了这里的所有步骤,交换名称和数字的问题通常是另一个awk '{print$2,$3,$1}'
管道的简单扩展(正如AFAbyss建议的那样,归功于他们!)或者通过sed -s "s/^\s\+\([0-9]\+\) \(.*\)$/\2 \1/"
(其中说:找到一个数字序列后跟一个空格和一个任意字符串直到行尾,输出后者,一个空格和前者,并且具有不处理的轻微优势“Internet Explorer”作为两个字段,并且不期望没有浏览器名称最多只有两个字)。这应该工作,为什么不呢?令人不安的是,你的线条与预期的差别很大!
因此,输出被破坏的问题在其他地方,我几乎可以肯定它是行尾格式。请注意,在不同的系统中,行尾由不同的字符或字符组合标记:
LF (\n, \012) on Unices,
CR (\r, \015) on classic Macs,
CRLF (\r\n, \015\012) on Windows
(heavily simplified)。如果您的文件是Microsoft Windows格式,Unix将读取\r
作为该行的一部分!让我们看看典型行中会发生什么:
...|196.223.11.62|Firefox\r\n
=========
field 8
包含Firefox
的所有行都会发生这种情况(因为它始终是最后一项,因此后面总是\r\n
),因此sort
和uniq
会这样做他们的工作很好,告诉你Firefox\r
出现了4182次:
4182 Firefox\r\n
==== =========**
cnt output EOL
这是一个不可见的问题。 \r
做的是回车,它会将光标返回到行的开头。以下\n
前进到下一行。想打字机:一直向右推,然后拉动手柄。在电子打字机中,它只是一个NL键按下,这就是为什么Unix会记录它的原因,\r
现在是多余的,但如果它刚好在\n
之前就不会破坏输出。
但是现在当你尝试交换线路的两个部分时:
Firefox\r 4182\n
========= ====**
output cnt EOL
这是一场灾难。打印Firefox
,然后马车返回最左侧的列,然后打印4182
重写之前键入的内容。数字之前实际上有两个空格,因为您指示awk
打印$2
,然后$3
(空),然后$1
,awk
插入空格两者之间。你会得到
Firefox\r (field $2 is printed, resulting in the carriage returned to left)
↑
␣irefox\r (space between $2 and $3)
↑
␣irefox\r (field $3 is printed)
↑
␣␣refox\r (space between $3 and $1)
↑
␣␣4812x\r (field $1 is printed)
↑
然后换行。这不是一个错误,它是一个常用于程序的功能,它有兴趣重写最后一行,而不必每次都输出一个新行(mplayer
,wget
,...)。错误是在输入行的末尾有一个额外的\r
。
一种方法是通过dos2unix
运行您的整个输入,将\r\n
的任何出现转换为\n
。但这不是必要的。如果您使用我的sed
替代方案,只需告诉它在正则表达式中\r
而不是\n
($
)之前停止:
grep -v \# file \
| cut -d \| -f 8 \
| sort \
| uniq -c \
| sed -s "s/^\s\+\([0-9]\+\) \(.*\)\r/\2 \1/"
↑↑