고정되지 않은 열 번호가 포함된 입력 파일이 있고 이에 대한 산술 계산을 수행하려고 합니다.
input.txt
ID1 4651455 234 4651765 392 4652423 470
ID2 16181020 176 16184958 869 16185889 347 16187777 231
입력 파일에는 열 내에서 ID
항상 고유한 (반복되지 않음) 탭으로 구분된 필드가 있습니다. $1
모든 행에 동일한 수의 열이 있는 것은 아닙니다.
내가 달성하려는 것은 다음과 같이 탭으로 구분된 파일입니다.
output1.txt
ID1 76 266
ID2 3762 62 1541
기본적으로 원본 파일을 인쇄한 $1
다음 파일의 두 번째 짝수 열( )에서 시작하여 처음 두 열( - - ) $4
의 값을 뺀 다음 입력 파일의 모든 짝수 열에 대해 동일한 작업을 수행합니다(예: 예, - - ; - - ; ...). 내가 아는 한 이 작업은 를 통해 수행할 수 있지만 내 파일에 행당 고정된 수의 열이 있는 경우에만 이를 처리하는 방법을 알고 있습니다.$4
$3
$2
$6
$5
$4
$8
$7
$6
awk print
내 요구 사항을 충족하는 더 이상적인 출력은 다음과 같습니다.
output2.txt
ID1 234 76 392 266 470
ID2 176 3762 869 62 347 1541 231
기본적으로 원본 파일을 인쇄 $1
한 다음 입력 파일의 홀수 열을 output1.txt
.
답변1
$ awk -v OFS='\t' -f script.awk file
ID1 76 266
ID2 3762 62 1541
script.awk
어디
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }
파일의 각 입력 줄에 대해 모든 블록이 실행됩니다.
첫 번째 블록은 ID를 출력합니다.
두 번째 블록은 사용자가 설명하는 대로 필드를 반복하고 OFS
(출력 필드 구분 기호, 명령줄의 탭으로 설정)로 구분된 데이터를 출력합니다.
마지막 블록은 RS
기본적으로 개행인 레코드 구분 기호를 출력합니다.
또는,
BEGIN { OFS = "\t" }
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }
옳아야 할 필요성을 없애십시오 -v OFS='\t'
.
"한 줄"로:
$ awk 'BEGIN { OFS = "\t" }
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }' file
확장 질문의 경우:
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d%s%d", OFS, $(i-1), OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s%d%s%s", OFS, $NF, OFS, RS) }
그러면 원본 파일에서 직접 다음이 생성됩니다.
ID1 234 76 392 266 470
ID2 176 3762 869 62 347 1541 231
답변2
앗해결책:
awk '{ r=$1; for(i=4;i<=NF;i+=2) r=r"\t"$i-$(i-1)-$(i-2); printf "%s\n",r }' OFS='\t' file
r=$1
- 첫 번째 필드 캡처for(i=4;i<=NF;i+=2)
- 반복심지어필드$i-$(i-1)-$(i-2)
- 필요한 뺄셈을 수행합니다.
산출:
ID1 76 266
ID2 3762 62 1541