リストを繰り返して最良の解決方法を知らない興味深い問題があります。次の形式で -
element, date, unixTime, value
CZ, 12/27/2007 15:55, 1198788900, 42346
CZ, 12/27/2007 17:30, 1198794600, -10543
I, 12/27/2007 19:05, 1198800300, 4475
各固有要素と各日付を繰り返して、「値」列の符号を取得したいと思います。たとえば、2007 年 12 月 27 日に、CZ と I に対してそれぞれ 1 つずつ 2 つの行が必要です。一日の終わりに発生する行が負の値を持つため、CZは負で、Iは正です。次に、12/28、12/29などのさまざまな要素に対してこれをやり直します。入れ子になったforループを使用して繰り返すことはできますが、ファイルが大きいため、日付ごとにソートされたファイルを一度だけ繰り返す方法を見つけるのが良いでしょう。これを最も効率的に行う方法については少し混乱しています。 bashがこれに適しているのか、PerlやPythonなどの他の言語が適しているのかわかりません。
答え1
入力データを呼び出してみましょう金持ち:
echo 'element, date, unixTime, value
CZ, 12/27/2007 15:55, 1198788900, 42346
CZ, 12/27/2007 17:30, 1198794600, -10543
I, 12/27/2007 19:05, 1198800300, 4475' > foo
走る牛に似た一種の栄養 datamash
存在する金持ち:
datamash -t, --header-in -g 1 last 4 < foo
出力:
CZ, -10543
I, 4475
より正式なスイッチ名を使用すると、上記のdatamash
内容がより明確になり、ヘッダー名が追加されました(計算された列が不便な場合)。
datamash --field-separator=',' --header-in --group=element last " value" < foo
答え2
@agcが目的の出力を正しく解釈したと仮定すると、通常のawk
古いバージョンを使用できます。
awk -F, 'NR>1{a[$1]=$4}END{for(x in a){print x","a[x]}}' foo
CZ, -10543
I, 4475
答え3
ファイルが事前にソートされているという事実を通してsed
。sed pattern space
2 lines
sed -e '
$!{
N
/^\([^,]*\),[[:space:]]\{1,\}\([^[:space:]]\{1,\}\)[[:space:]].*[[:space:]]\([^[:space:]]\{1,\}\)\n\1,[[:space:]]\{1,\}\2[[:space:]]/D
}
s/^\([^,]*\),[[:space:]]\{1,\}\([^[:space:]]\{1,\}\)[[:space:]].*[[:space:]]\([^[:space:]]\{1,\}\)\(\n\)/\1 \3\4/
/\n/!s/^\([^,]*\),[[:space:]]\{1,\}\([^[:space:]]\{1,\}\)[[:space:]].*[[:space:]]\([^[:space:]]\{1,\}\)/\1 \3/
P;D
' yourfile
単に
We always keep 2 lines in the pattern space and note the time when there
is a change in the 1st field. So long as we keep encountering the same
first two fields, we keep chopping off the previous line and reading in
the next. And on a transition we print the 1st and last fields of the
previous line, print it, remove upto the newline, and go back for more
with whats left in the pattern space.