유닉스 패키지datamash
다중 집계 작업을 지원하는 애플리케이션그룹줄 수를 입력하세요. 예를 들어 1 은 다음과 같이 datamash
열 1의 각 값에 대한 열 2의 합계를 계산하는 데 사용됩니다.
$ cat example.csv
1,10
1,5
2,9
2,11
$ datamash -t, -g 1 sum 2 < example.csv
1,15
2,20
지원되는 기능 datamash
도 매우 넓지만 ( , , , , 등 sum
포함 ) 확장이 불가능합니다. AFAICT. IOW에서는 사용자가 자신의 요약 기능을 제공할 수 있는 메커니즘이 지원되지 않습니다.mean
stddev
median
iqr
min
max
datamash
내 질문은 다음과 같습니다. 일반적으로 zsh
2 에서 이러한 종류의 명령별 그룹 응용 프로그램을 어떻게 구현할 수 있습니까?
아래에서는 문제를 더 정확하게 설명하려고 합니다. (정확한 시도로 인해 질문을 이해할 수 없게 되지 않기를 바랍니다.)
먼저, foo
이것이 다음 구조를 사용하여 stdout 라인으로 전송된 (복합 가능) 명령을 나타낸다고 가정합니다.
나 분할기 페이로드 i j
...어디나, "그룹 인덱스"는 정수입니다.분할기상수 구분 기호 시퀀스(예: ,
, 또는 $'\t'
)입니다.페이로드 i j임의의 텍스트입니다(종료 문자 포함). 또한 그룹 인덱스를 가정하면나범위는 1부터질소, 이 출력의 행은 그룹 인덱스에 따라 정렬됩니다.
모든 정수에 대해 1 ≤ 케이 ≤ 질소,허락하다"케이"그룹 -"은 조각으로 구성된 콘텐츠를 나타냅니다.페이 로드 kjfoo
그룹 인덱스가 있는 모든 행( 의 출력)케이.
다음으로, 이것이 bar
stdin에서 행을 읽고 발행하는 (복합일 수도 있는) 명령을 나타낸다고 가정합니다.하나의 선표준 출력으로.
이제결과케이bar
다음에 적용된 출력을 나타냅니다.케이-번째 그룹, X<bar>
호출하는 쉘 구성을 표현해 보겠습니다 bar
.
나는 기본적으로 X<bar>
파이프를 만드는 구조물을 찾고 있습니다.
foo | X<bar>
양식의 stdout 라인으로 전송됩니다.
나 분할기 결과나
편집하다:
가설분할기그렇다면 ,
다음은 내 요구 사항을 충족하는 것 같습니다.
TMPFILE=$( mktemp )
SEPARATOR=,
LASTGROUPID=
foo | (cat; echo) | while IFS= read -r LINE
do
GROUPID=${LINE%%$SEPARATOR*}
if [[ $GROUPID != $LASTGROUPID ]]
then
if [[ -n $LASTGROUPID ]]
then
echo -n "$LASTGROUPID$SEPARATOR"
cat $TMPFILE | bar
fi
LASTGROUPID=$GROUPID
: > $TMPFILE
fi
PAYLOAD=${LINE#*$SEPARATOR}
echo $PAYLOAD >> $TMPFILE
done
rm $TMPFILE
$TMPFILE
기본적으로 이는 다음 그룹의 행을 수집 하는 데 사용됩니다 . (임시파일은 피하고 싶은데 어떻게 해야할지 모르겠습니다.)
bar
이제 표현된 표현식을 매개 변수로 사용하고 위에 제공된 구문에서 이를 강력하게 사용할 수 있는 함수로 이를 구현하는 방법을 찾아야 합니다 .
1이datamash
예는 매뉴얼 페이지에 제공된 예를 수정한 것입니다 .
2 나는 일차적인 관심이 있지만 부차적인 관심도 가지고 있습니다 zsh
.bash
답변1
나에게 이것은 쉘 작업처럼 보이지 않습니다. 나는 이렇게 할 것이다 perl
... 비록 여기면 충분할 수도 있지만:python
ruby
awk
$ cat sum
paste -sd + - | bc
$ sort -t , -k 1,1 input | awk -F, -v cmd=./sum '
function out() {printf "%s,", l;close(cmd)}
NR>1 && $1 != l {out()}
{print $2 | cmd; l=$1}
END {if (NR) out()}'
1,15
2,20
답변2
당신이 찾고 있는 것이 무엇인지 알고 있다면: 샘플 세트에서 분포를 생성하는 것과 유사하지만 더 많은 누적 옵션이 있는 스크립트입니다. 나는 awk
이것을 위해 스크립트를 작성했습니다.
https://drive.google.com/open?id=0B0Kg_QLltwbNU21zbHFMY1hnSjQ
이는 정확히 원하는 것이 아니지만 겹치는 부분이 커야 합니다. 첫째 - 인덱스는 정수일 뿐만 아니라 둘째 - 유일한 누적 방법은 합계입니다. 하지만 단순한 스크립트이기 때문에 C 프로그램보다 쉽게 수정할 수 있습니다.
마지막으로 이러한 스크립트는 데이터 세트가 충분히 작은 경우에만 작동하며, 더 큰 데이터 세트의 경우에는 너무 느립니다! 따라서 보다 전문적인 패키지가 더 좋습니다( R
등).
PS 추가 누산기를 추가하려면 +=
사용자 정의 함수("monad")로 바꾸십시오.