输入:
user@server:~/bar/foobar$ SAT=$(date -dsaturday +%Y-%m-%d); SUN=$(date -dsunday +%Y-%m-%d)
user@server:~/bar/foobar$ awk 'BEGIN {FS="'^'"} {print $1"\t"$3"\t"$6}' STs.csv STt.csv | egrep -w "${SAT}|${SUN}" | sort -u
'ST30074650' '2015-10-17 10:00'
'ST30074650' '[email protected]' '2015-10-17 10:00'
'ST30085367' '[email protected]' '2015-10-18 13:00'
'ST30086369' '2015-10-17 13:00'
'ST30115016' '[email protected]' '2015-10-18 13:00'
'ST30124587' '2015-10-18 09:00'
'ST30123591' '2015-10-18 09:00'
user@server:~/bar/foobar$
所需输出:
user@server:~/bar/foobar$ SAT=$(date -dsaturday +%Y-%m-%d); SUN=$(date -dsunday +%Y-%m-%d)
user@server:~/bar/foobar$ awk 'BEGIN {FS="'^'"} {print $1"\t"$3"\t"$6}' STs.csv STt.csv | egrep -w "${SAT}|${SUN}" | sort -u | SOMEMAGIC
'ST30074650' '[email protected]' '2015-10-17 10:00'
'ST30085367' '[email protected]' '2015-10-18 13:00'
'ST30086369' '2015-10-17 13:00'
'ST30115016' '[email protected]' '2015-10-18 13:00'
'ST30124587' '2015-10-18 09:00'
'ST30123591' '2015-10-18 09:00'
user@server:~/bar/foobar$
问题:因此,如果第一列重复,例如:“ST30074650” - 应该只保留较长的行。怎么有人在“SOMEMAGIC”能做到这一点。
答案1
我不明白 SOMEMAGIC 与它有什么关系
试试这个 awk 文件
{ if ( $1 in a ) {
if ( length(a[$1]) < length($0)) a[$1]=$0 ;
} # $1 in a
else a[$1]=$0 ; }
END { for ( b in a ) {print a[b] ;} }
使用它(无需预排序)
... egrep -w "${SAT}|${SUN}" | awk -f u.awk | sort
答案2
使用 perl 一行:
perl -a -e '$line{$F[0]} = $_ if (length($_) > length($line{$F[0]})) ; END { foreach (sort keys %line) { print $line{$_} } };' STs.csv STt.csv
或者,采用更易于阅读的独立 Perl 脚本形式:
#! /usr/bin/perl -a
$line{$F[0]} = $_ if (length($_) > length($line{$F[0]})) ;
END {
foreach (sort keys %line) { print $line{$_} }
};
这本质上是与Archemar的答案相同的算法,但是是inperl
而不是awk
.简单来说:使用输入的第一个字段作为散列数组的键,如果输入的当前行比我们为数组存储的长(默认为 perl 中的空字符串),则存储当前行。一旦我们读取了所有输入(即完成),就打印出哈希的每个元素。
答案3
user@machine:~/tmp$ cat f1
'ST30074650' '[email protected]' '2015-10-17 10:00'
'ST30085367' '[email protected]' '2015-10-18 13:00'
'ST30086369' '2015-10-17 13:00'
'ST30115016' '[email protected]' '2015-10-18 13:00'
'ST30124587' '2015-10-18 09:00'
'ST30123591' '2015-10-18 09:00'
'ST30074650' '2015-10-17 10:00'
user@machine:~/tmp$ sort -r f1 |uniq -w 12 |sort
'ST30074650' '[email protected]' '2015-10-17 10:00'
'ST30085367' '[email protected]' '2015-10-18 13:00'
'ST30086369' '2015-10-17 13:00'
'ST30115016' '[email protected]' '2015-10-18 13:00'
'ST30123591' '2015-10-18 09:00'
'ST30124587' '2015-10-18 09:00'
- 首先对整行按相反顺序排序,以首先获得较长的行
- uniq 仅检查前 12 个字符将保留仅比较 12 个字符的第一(较长)行
- 可选的最终排序以获得自然顺序
答案4
重构您的代码(由于缺乏原始输入数据而未经测试)
awk -F '^' -v OFS='\t' \
-v sat=$(date -d saturday +%F) \
-v sun=$(date -d sunday +%F) \
'
$6 !~ "^"sat && $6 !~ "^"sun {next}
{ line = $1 OFS $3 OFS $6 }
length(line) > lines[$1] {lines[$1] = line}
END { for (key in lines) print lines[key] }
' STs.csv STt.csv | sort
sort
使用 GNU awk,您可以通过使用省略尾随
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
for (key in lines) print lines[key]
}