在保持文件结构的同时乘以 x-end 列

在保持文件结构的同时乘以 x-end 列

我的输入 File1 如下所示:

A,22,1,2,3,4,5
G,26,5,6,7
X,28,10,20,10

我想在保持文件结构的同时将方程应用于第 3 列。例如,如果我想要使用的方程乘以 2,我正在寻找输出:

A,22,2,4,6,8,10
G,26,10,12,14
X,28,20,40,20

我尝试使用以下命令来执行此操作:

awk -F ',' '{for(i=1; i<=NF; i++) if (i >= 3)
     print 2*$i
  else
    print $i }' File1

这提供了正确的输出,但消除了所有文件结构。如果使用我想要使用的实际方程是: 2*(2*($i-1)+1)

非常感谢解决方案附带的任何解释,因为我对此仍然很陌生!

答案1

您只需设置输出字段分隔符(OFS),例如:

awk '{ for (i=3; i<=NF; i++) $i*=2 } 1' FS=, OFS=, infile

或者使用你的公式:

awk '{ for (i=3; i<=NF; i++) $i = 2*(2*($i-1)+1) } 1' FS=, OFS=, infile

输出:

A,22,2,4,6,8,10
G,26,10,12,14
X,28,20,40,20

脚本末尾的1是以下内容的简写{ print $0 }

答案2

Perl可以解决如下所示:基于@Thor的建议:

$ perl -F, -anE '$,="," ; say splice(@F,0,2), map { 2*(2*($_-1)+1) } @F' inp.csv

使用另一种方法:

$ perl -lpe '
   /^[^,]*,[^,]*/g; #positions the search engine before the 2nd comma.
   s/\G,\K([^,]*)/2*(2*($1-1)+1)/ge;
' inp.csv

GNU 桌面计算器实用程序可以执行以下操作:

$ < inp.csv tr ',-'  ' _' | sed -Ee 's/\S+/[&]/' |
    dc -e "
     [q]sq
     [44an]s,
     [1-2*1+2*]s=
     [SM lN1+sN z0<a]sa
     [LMnl,x LMnl,x lN2-sN]sb
     [LMl=xn lN1<, lN1-dsN0<c]sc
     [?z0=q 0sN lax lbx lcx 10an z0=?]s?
     l?x
"

这些是简单的实用程序和根据要求进行的解释,因为这些是简单明了的代码。

简要说明:

dc实用程序在堆栈上工作,在堆栈上存储数据和代码。从这里开始,它将 n 个检索存储在寄存器中。

字符串数据用方括号括起来。

删除是通过递归完成的。

在这个dc代码中有7个寄存器存储代码,即q = , abc ?

两个寄存器MN存储数据。

从最后开始倒推。代码寄存器?执行从输入读取下一行的操作。然后比较其堆栈上有多少个空格分隔的项目;将它们视为字段。如果是 0 ,则停止 n 退出。 z0=q 片段就是这样做的。它的读法是: z 是返回存在元素数量的 dc 命令。我们与 0 进行比较,如果相等,则执行寄存器 q 中存储的代码。

答案3

s=`awk '{print NR}' p.txt| sort -nr | sed -n '1p'`
praveen@praveen:~$ for ((i=1;i<=$s;i++)); do m=`awk -v i="$i" -F "," 'NR==i{print NF}' p.txt`; for ((u=1;u<=$m;u++)); do if [[ $u < 3 ]]; then awk -v  i="$i" -v  u="$u" -F ","  'NR==i{print $u}'  p.txt; else awk -v i="$i" -v u="$u" -F "," 'NR==i {print 2*$u}' p.txt; fi; done| sed "N;s/\n/,/g"| sed "N;s/\n/,/g"| sed "N;s/\n/,/g"; done

where p.txt is filename



A,22,2,4,6,8,10
G,26,10,12,14
X,28,20,40,20

相关内容