如何用最后一个值替换整列?

时间:2014-07-26 11:25:45

标签: 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

但它不起作用,我不明白为什么......

请帮忙!

3 个答案:

答案 0 :(得分:2)

awk '
    BEGIN { ARGV[2]=ARGV[1]; ARGC++; FS=OFS="," }
    NR==FNR { last = $3; next }
    { $3 = last; print }
' math_ready.csv > math1.csv

您的脚本的主要问题是尝试访问awk脚本中的shell变量($var)。 awk不是shell,它是一个完全独立的语言/工具,它有自己的命名空间和变量。您不能直接访问awk中的shell变量,就像您无法在C中访问它一样。要访问shell变量的VALUE,您需要执行以下操作:

shellvar=27
awk -v awkvar="$shellvar" 'BEGIN{ print awkvar }'`

一些额外的清理:

  1. 当FS和OFS具有相同的值时,请不要将它们分别分配给该值,而是使用BEGIN{ FS=OFS="," }代替清晰度和可维护性。
  2. 除非您有非常明确的理由,否则请勿在使用这些变量的脚本之后对变量进行iniatailize。使用awk -F... -v OFS=... 'script'初始化这些变量来分隔值,而不是awk -F... 'script' OFS=...,因为它在您使用它们之后对代码段中的初始变量非常不自然,并且末尾的args列表中的变量未初始化执行BEGIN部分时可能会导致错误。

答案 1 :(得分:1)

shell变量在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

答案 2 :(得分:0)

试试这个衬垫。它不依赖于列数

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

输出:

24,1,2,30,678
33,4,5,61,678
66,7,8,91111,678
76,10,11,32,678