datamash를 사용하여 모든 열에서 작업하는 방법은 무엇입니까?

datamash를 사용하여 모든 열에서 작업하는 방법은 무엇입니까?

다음과 같은 데이터 파일이 있다고 가정해 보겠습니다.

111 222 333
444 555 666
777 888 999

GNU Datamash를 사용하여 다음과 같이 각 열의 합계를 계산할 수 있습니다.

cat foo | datamash -t\  sum 1 sum 2 sum 3
1332 1665 1998

데이터 파일의 열 수를 모르는 경우 datamash를 사용하여 이 작업을 어떻게 수행합니까?

예를 들어 필드 선택기 cut와 같은 범위 종료 기호를 지원하기 때문에 이 질문을 하는 것입니다 .-

답변1

알 수 없는 범위를 지정하는 옵션이 표시되지 않습니다.데이터 혼합 핸드북

perl단 하나의 라이너를 사용해보십시오

$ perl -lane '$s[$_]+=$F[$_] for 0..$#F; END{print join " ", @s}' ip.txt
1332 1665 1998
  • -a옵션은 자동으로 입력 줄을 공백으로 분할하고 결과를 @F배열 에 저장합니다.
  • for 0..$#F배열을 반복하여 $#F마지막 요소의 인덱스 제공
  • $s[$_]+=$F[$_]합계를 @s배열에 저장하면 기본적으로 초기 값은 0숫자 컨텍스트에 있습니다. $_각 반복에는 인덱스 값이 있습니다.
  • END{print join " ", @s}모든 입력 행이 처리된 후 @s공백을 구분 기호로 사용하여 배열 내용을 인쇄합니다.

답변2

cols=$( awk '{print NF; exit}' foo); cat foo | datamash -t\  sum 1-$cols

또는

cat foo | datamash -t\  sum 1-$( awk '{print NF; exit}' foo)

datamash열 범위를 지정하는 기능이 있으므로 열 수를 계산하고 그 결과를 범위 지정의 일부로 사용합니다. 내 예제 솔루션에서는 awk파일의 첫 번째 줄을 확인하고 종료했지만 자신에게 적합한 다른 항목을 사용할 수 있습니다. 출력에 열 번호가 포함된 datamash함수 자체가 있지만 -check해당 형식에서는 여전히 관심 있는 특정 숫자를 구문 분석해야 합니다.

답변3

잘 모르겠지만 해결책 datamash은 다음과 같습니다 awk.

$ awk '{ for( col=1; col<=NF; col++ ) { totals[col]+=$col } } END { for( col=0; col<length(totals); col++ ) {printf "%s ", totals[col]}; printf "\n" } ' input
1332 1665 1998

awk이 스크립트를 더 읽기 쉽게 만들려면 다음을 수행하세요 .

{      // execute on all records
  for( col=1; col<=NF; col++ ) { 
    totals[col]+=$col 
  }; 
} 
END {  // execute after all records processed
  for( col=0; col<length(totals); col++ ) {
    printf "%s ", totals[col]
  }; 
  printf "\n";
} 

답변4

사용 datamashbash:

n=($(datamash -W check < foo)); datamash -W sum 1-${n[2]} < foo

산출:

1332    1665    1998

작동 방식:

  1. datamash -W check < foo출력 문자열"3개의 행, 3개의 필드".

  2. n=($(datamash -W check < foo))문자열을 배열로 로드합니다 $n. 우리는 필드 수, 즉 ${n[2]}.

  3. datamash -W sum 1-${n[2]} < foo나머지는 완료되었습니다.


이 작업은 다음을 통해 수행할 수도 있습니다.POSIXprintf에서는 배열 대신 복잡한 형식의 문자열을 사용하지만 더 조잡합니다.

datamash -W sum 1-$(printf '%0.0s%0.0s%s%0.0s' $(datamash -W check < foo)) < foo

이 작업은 셸 도구를 사용하여 수행할 수도 있습니다.

datamash -W sum 1-$(head -1 foo | wc -w) < foo

관련 정보