入力する:
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 1行使用:
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の答えと同じアルゴリズムですが、代わりに簡単にperl
言え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]
}