计算相邻列之间的所有差异

时间:2014-04-17 14:27:23

标签: awk sed

我在一个文件中有这样的数据,如下所示

60.5(r) 426.5(f) 810.5(r) 1176.5(f) 1560.5(r) 1926.5(f) 2310.5(r) 2676.5(f) 3060.5(r) 3426.5(f) 3810.5(r) 4176.5(f) 4560.5(r) 4926.5(f) 5310.5(r) 5676.5(f) 6060.5(r) 6426.5(f) 6810.5(r) 7176.5(f) 7560.5(r) 7926.5(f) 8310.5(r)

每一件事都在同一行,我想计算所有列的[第二列 - 第一列] [第三列 - 第二列]的差异,并在另一个文件中复制(在不同的行中)

我的尝试:

awk '{for (i=3;i < NF;i++) print $i}' > file.txt

但我不知道如何删除(r)(f)并同时处理差异并复制到其他文件中

4 个答案:

答案 0 :(得分:1)

$ echo '60.5(r) 426.5(f) 810.5(r) 1176.5(f) 1560.5(r) 1926.5(f) 2310.5(r) 2676.5(f) 3060.5(r) 3426.5(f) 3810.5(r) 4176.5(f) 4560.5(r) 4926.5(f) 5310.5(r) 5676.5(f) 6060.5(r) 6426.5(f) 6810.5(r) 7176.5(f) 7560.5(r) 7926.5(f) 8310.5(r)' \
| awk -F'[()fr]+' '
    {for (i = 2; i < NF; i++) { 
        printf("%d ", $i - $(i-1))
    } print ""}'
366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 

修订基于sudo_O's回答:

$ echo '60.5(r) 426.5(f) 810.5(r) 1176.5(f) 1560.5(r) 1926.5(f) 2310.5(r) 2676.5(f) 3060.5(r) 3426.5(f) 3810.5(r) 4176.5(f) 4560.5(r) 4926.5(f) 5310.5(r) 5676.5(f) 6060.5(r) 6426.5(f) 6810.5(r) 7176.5(f) 7560.5(r) 7926.5(f) 8310.5(r)' \
| awk -v RS='[()fr]+' -v ORS=' ' '
    1 < NR && NF {print $i - x} 
    {x = $1} 
    END {print "\n"}'
366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 

修订基于JS웃's回答

awk 'BEGIN {RS=FS;ORS=" "}
    1 < NR && NF {print $i - x} 
    {x = $1} 
    END {print "\n"}'
366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 

答案 1 :(得分:1)

打印连续列之间的差异,每行输出一个:

$ awk 'NR>1&&NF{print $1-x}{x=$1}' RS='[(][rf][)]' file 

只需重定向输出以保存到新文件:

$ awk 'NR>1&&NF{print $1-x}{x=$1}' RS='[(][rf][)]' file > new_file 

如果您想将差异全部放在一行:

$ awk 'NR>1&&NF{print $1-x}{x=$1}' RS='[(][rf][)]' file | xargs > new_file 

答案 2 :(得分:0)

如果您只想要第2列和第1列以及第3列和第2列之间的差异:

awk '{gsub("\\([^)]*\\)",""); print $2 - $1, $3 - $2 }' input-file > output-file

如果您想要所有列之间的区别:

 awk '{gsub("\\([^)]*\\)",""); for(i=2; i<= NF; i++) print $i - $(i-1)}' input > output

如果您希望输出与inupt具有相同的行数,请尝试:

awk '{gsub("\\([^)]*\\)","");
  for(i=2; i<= NF; i++) printf " %d", $i - $(i-1); print ""}'

要获得更多表格输出,请使用printf "%15d"或其他一些格式字符串。

答案 3 :(得分:0)

您实际上不需要明确地删除(r)(f)。当您对包含字符的字段执行数学运算时,它们会自动脱落。它被称为胁迫。因为在您的情况下,非数字字符位于数字之后,您可以简单地执行:

$ awk '{for(i=2;i<=NF;i++) printf "%d%s",$i-$(i-1),(i==NF?RS:FS)}' data
366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384 366 384