datamash
나는 경험이 풍부한 사용자임을 알고 있습니다 awk
. ratio 를 찾고 있습니다 awk
. 다음이 있다고 가정해 보겠습니다.
// data_file
foo bar biz
10 100 1000
11 150 990
10 95 1010
9 99 950
// usage goal, in pseudo code
cat data_file | <tool> --ratio foo,bar --ratio foo,biz --ratio bar,biz
// desired output
foo bar biz foo_bar foo_biz bar_biz
10 100 1000 0.1 0.01 0.1
11 150 990 0.073 0.011 0.1515
10 95 1010 0.105 0.0099 0.094
9 99 950 0.09 0.0095 0.1042
이 인터페이스를 얻기 위해 C++로 간단한 것을 만들겠습니다.
그때까지 Unix에는 간단한 해결책이 있습니까?
답변1
밀러 사용(https://github.com/johnkerl/miller) 그리고 실행
mlr --pprint put '$foo_bar=$foo/$bar;$foo_biz=$foo/$biz;$bar_biz=$bar/$biz' input >output
당신은
foo bar biz foo_bar foo_biz bar_biz
10 100 1000 0.100000 0.010000 0.100000
11 150 990 0.073333 0.011111 0.151515
10 95 1010 0.105263 0.009901 0.094059
9 99 950 0.090909 0.009474 0.104211
답변2
몇 가지 bash 기능을 사용하면 paste
작업하려는 파일이 있는 경우 bc
매우 직접적으로 이동할 수 있습니다.csvtool
div() {
printf "%1.4f\n" $(bc -l <<<"1.0 * $1 / $2")
}
export -f div
ratio() {
echo "$1"_"$2"
csvtool -t ' ' namedcol $1,$2 data.ssv |
tail -n+2 |
csvtool call div -
}
paste -d ' ' <(cat data.ssv) <(ratio foo bar) <(ratio foo biz) <(ratio bar biz) |
csvtool -t ' ' readable -
산출:
foo bar biz foo_bar foo_biz bar_biz
10 100 1000 0.1000 0.0100 0.1000
11 150 990 0.0733 0.0111 0.1515
10 95 1010 0.1053 0.0099 0.0941
9 99 950 0.0909 0.0095 0.1042
정말로 스트림으로 수행하고 싶다면 가장 좋은 방법은 아마도 awk
다음과 같습니다.
파싱.awk
# Parse the requested column ratios into dividend[] and divisor[]
# by column name
BEGIN {
split(ratios_str, ratios, / +/)
for(r in ratios) {
split(ratios[r], cols, /,/)
dividend[++i] = cols[1]
divisor[i] = cols[2]
}
}
# Sort out the header
NR == 1 {
# Create the ColumnName-to-ColumnNumber hash
split($0, a); for(k in a) c2n[a[k]]=k
# Print the header line
printf "%s ", $0
for(i=1; i<=length(dividend); i++)
printf "%s_%s ", dividend[i], divisor[i]
printf "\n"
}
NR > 1 {
printf "%s ", $0
for(i=1; i<=length(dividend); i++)
printf "%1.4f ", $(c2n[dividend[i]]) / $(c2n[divisor[i]])
printf "\n"
}
다음과 같이 실행하세요:
<data.ssv awk -f parse.awk -v ratios_str='foo,bar foo,biz bar,biz' | column -t
산출:
foo bar biz foo_bar foo_biz bar_biz
10 100 1000 0.1000 0.0100 0.1000
11 150 990 0.0733 0.0111 0.1515
10 95 1010 0.1053 0.0099 0.0941
9 99 950 0.0909 0.0095 0.1042