我的文件有 27 列和 45000 行
head test_1
0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0
16 20 24 20 20 10 6 28 36 10 26 14 24 24 24 30 24 30 24
2 8 2 4 2 0 0 10 8 2 6 0 6 4 4 6 2 10 2
14 12 22 16 18 10 6 20 28 8 20 14 18 20 20 24 22 20 22
0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 0 0 2 0
16 20 24 20 20 10 6 30 36 10 26 14 24 24 24 28 22 30 24
0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
我想使用 shell 脚本将每个值除以某个常数(此处为 2)。我该怎么做?我尝试过类似的方法awk -v c=2 '{ print $0/c }' test_1
,但它只打印第一列!
答案1
是的,awk -v c=2 '{ print $0/c }' test_1
只会打印第一列,因为它会尝试用 来划分每个完整的行c
。将行转换为单个数字会丢弃所有非数字的内容,即第一个空格及其后的所有内容。
相反,您需要循环遍历列:
awk -v c=2 '{ for (i = 1; i <= NF; ++i) $i /= c; print }' OFS='\t' test_1
此代码只是将每列的值设置为自身除以c
,然后打印包含修改值的行。NF
是当前行上的字段(列)数,并且$i
将是 column 中的值i
。最后OFS='\t'
将输出字段分隔符设置为制表符。
给定数据的结果将是
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
8 10 12 10 10 5 3 14 18 5 13 7 12 12 12 15 12 15 12
1 4 1 2 1 0 0 5 4 1 3 0 3 2 2 3 1 5 1
7 6 11 8 9 5 3 10 14 4 10 7 9 10 10 12 11 10 11
0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0
8 10 12 10 10 5 3 15 18 5 13 7 12 12 12 14 11 15 12
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
答案2
非常接近,但你需要单独划分每一列:
awk -v denominator=2 '{ for( i=0;i<=NF;i++ ) { printf "%f%s", $i/denominator, OFS }; printf "%s", ORS }' /path/to/file