Shell 如何用最后一个值替换整列?
我试图获取CSV文件第三列中的最后一个值,然后用这个值替换整个第三列 我一直在尝试:Shell 如何用最后一个值替换整列?,shell,csv,awk,Shell,Csv,Awk,我试图获取CSV文件第三列中的最后一个值,然后用这个值替换整个第三列 我一直在尝试: var=$(tail -n 1 math_ready.csv | awk -F"," '{print $3}'); awk -F, '{$3="$var";}1' OFS=, math_ready.csv > math1.csv 但它不起作用,我不明白为什么 请帮忙 外壳变量在awk中不能在内部展开。您可以这样做: awk -F, -v var="$var" '{ $3 = var } 1' OFS=,
var=$(tail -n 1 math_ready.csv | awk -F"," '{print $3}'); awk -F, '{$3="$var";}1' OFS=, math_ready.csv > math1.csv
但它不起作用,我不明白为什么
请帮忙 外壳变量在awk中不能在内部展开。您可以这样做:
awk -F, -v var="$var" '{ $3 = var } 1' OFS=, math_ready.csv > math1.cs
您可能可以通过以下方式简化代码:
awk -F, 'NR == FNR { r = $3; next } { $3 = r } 1' OFS=, math_ready.csv math_ready.csv > math1.csv
输入示例:
1,2,1
1,2,2
1,2,3
1,2,4
1,2,5
输出:
1,2,5
1,2,5
1,2,5
1,2,5
1,2,5
试试这一行。它不依赖于列计数
var=`tail -1 sample.csv | perl -ne 'm/([^,]+)$/; print "$1";'`; cat sample.csv | while read line; do echo $line | perl -ne "s/[^,]*$/$var\n/; print $_;"; done
cat sample.csv
24,1,2,30,12
33,4,5,61,3333
66,7,8,91111,1
76,10,11,32,678
输出:
脚本的主要问题是试图访问awk脚本中的shell变量($var
)。Awk不是shell,它是一种完全独立的语言/工具,有自己的名称空间和变量。您无法在awk中直接访问shell变量,就像在C中无法访问它一样。要访问shell变量的值,您需要执行以下操作:
shellvar=27
awk -v awkvar="$shellvar" 'BEGIN{ print awkvar }'`
一些额外的清理:
BEGIN{FS=OFS=“,”}
,以提高清晰度和可维护性awk-F…”脚本'OFS=…
,因为在使用完代码段中的变量后,在代码段中初始化变量是非常不自然的,并且在执行BEGIN部分时,在末尾的args列表中初始化的变量没有初始化,这可能会导致错误+1用于将仅适用于awk的解决方案与许多鲜为人知的功能结合使用谢谢!我更喜欢awk唯一的解决方案。但是你能详细解释一下它的逻辑吗?对不起,我是新来的shell编程人员;-)@Boriskryshev通过两次传递
math_ready.csv
我们让awk读两遍。节NR==FNR{r=$3;next}
以第一个循环为目标。它将每行的第三列读取为r
。最后一行将给出r
的最后一个值{$3=r}1
处理第二个循环。它用每行的r
值替换第三列1
与1{print}
同义,它总是为处理{print}
提供一个真实的条件print
打印当前记录。若要添加有关这两个部分如何分别处理两个会话的更多提示:NR==FNR{r=$3;next}
,NR==FNR
仅在第一个会话内有效,因为NR即使在第二个会话上也会不断增加,但FNR会重置回0。这就是该条件在下一个会话中不再有效的原因next
使awk
跳转到下一条记录,而不处理其后的任何语句。实际上,这使得{r=$3}
只为第一个循环运行,{{$3=r}1
只为第二个循环运行…。我只是发现这使我的答案复杂化。在有人向我证明这是未定义的行为之前,我也是这样做的,因此在某些AWK中,ARGC++
可以在赋值之前执行。从那时起,我通常使用ARGV[ARGC]=ARGV[ARGC-1];ARGC++
。考虑到这一点,但我也认为我的脚本只针对gawk运行。诚然,这是一个非常简单的解决方案,尽管将其特定于gawk似乎不值得,因为没有任何只针对gawk的功能使脚本变得更简单。我想,这是一个非常简单的解决方案。
awk '
BEGIN { ARGV[2]=ARGV[1]; ARGC++; FS=OFS="," }
NR==FNR { last = $3; next }
{ $3 = last; print }
' math_ready.csv > math1.csv
shellvar=27
awk -v awkvar="$shellvar" 'BEGIN{ print awkvar }'`