我有一个逗号分隔文件“myfile.csv”,其中第5列是日期/时间戳。 (mm / dd / yyyy hh:mm)。 我需要列出包含重复日期的所有行(有很多)
我正在通过cygwin使用bash shell for WinXP
$ cut -d, -f 5 myfile.csv | sort | uniq -d
正确返回重复日期列表
01/01/2005 00:22
01/01/2005 00:37
[snip]
02/29/2009 23:54
但我无法弄清楚如何将这个提供给grep给我所有的行。
显然,我不能直接使用xargs
,因为输出包含空格。我以为我可以做uniq -z -d
但是出于某种原因,组合这些标志会导致uniq(显然)没有返回任何内容。
所以,鉴于那个
$ cut -d, -f 5 myfile.csv | sort | uniq -d -z | xargs -0 -I {} grep '{}' myfile.csv
不起作用......我该怎么办?
我知道我可以用perl
或其他脚本语言执行此操作...但我固执的性质坚持认为我应该能够使用{{1}等标准命令行工具在bash
中执行此操作}},sort
,uniq
,find
,grep
等。
教我,哦,抨击大师。如何使用典型的cli工具获取所需的行列表?
答案 0 :(得分:10)
问题是如果#5之后的字段不同。你的约会时间长度是一样的吗?您可以将-w 16(包含时间)或-w 10(仅适用于日期)添加到uniq。
所以:
tr '\t' ',' < myfile.csv | sort -k5,5 | uniq -f 4 -D -w 16
答案 1 :(得分:2)
-z
的{{1}}选项需要将输入分为NUL。您可以通过以下方式过滤uniq
的输出:
cut
获得零分隔行。然后tr '\n' '\000'
,sort
和uniq
可以选择处理该问题。尝试类似:
xargs
编辑:管道中cut -d, -f 5 myfile.csv | tr '\n' '\000' | sort -z | uniq -d -z | xargs -0 -I {} grep '{}' myfile.csv
的位置错误。
答案 2 :(得分:1)
尝试使用sed转义空格:
echo 01/01/2005 00:37 | sed 's/ /\\ /g'
cut -d, -f 5 myfile.csv | sort | uniq -d | sed 's/ /\\ /g' | xargs -I '{}' grep '{}' myfile.csv
(另一种方法是将重复的日期行读入IFS = $'\ n'数组并在for循环中迭代它。)
答案 3 :(得分:0)
您可以使用-d选项告诉xargs使用每一行作为参数。尝试:
cut -d, -f 5 myfile.csv | sort | uniq -d | xargs -d '\n' -I '{}' grep '{}' myfile.csv
答案 4 :(得分:0)
这是awk的一个很好的候选人:
BEGIN { FS="," }
{ split($5,A," "); date[A[0]] = date[A[0]] " " NR }
END { for (i in date) print i ":" date[i] }