用bash中的另一个替换CSV文件中的列

时间:2013-06-28 16:15:03

标签: bash csv awk

我有一个包含多个列的csv文件。我试图用同一个文件中的倒数第二列替换第二列。 例如,如果我有一个文件,sample.csv

1,2,3,4,5,6
a,b,c,d,e,f
g,h,i,j,k,l

我想输出:

1,5,3,4,5,6
a,e,c,d,e,f
g,k,i,j,k,l

任何人都可以帮我完成这项任务吗?另请注意,我将使用cut函数丢弃最后两列,因此我打开将csv文件分开以便开始,以便我可以将一个csv文件中的列替换为另一个csv文件中的另一列。哪个更容易实现。提前感谢您的帮助。

3 个答案:

答案 0 :(得分:9)

这个简单的awk怎么样:

awk 'BEGIN{FS=OFS=","} {$2=$(NF-1)}'1 sample.csv

编辑:注意到您还想丢弃最后2列。使用这个awk one-liner:

awk 'BEGIN{FS=OFS=","} {$2=$(NF-1); NF=NF-2}'1 sample.csv

答案 1 :(得分:0)

在bash中

while IFS=, read -r -a arr; do
  arr[1]="${arr[4]}";  
  printf -v output "%s," "${arr[@]}"; 
  printf "%s\n" "${output%,}"; 
done < sample.csv

答案 2 :(得分:0)

解决方案,以有趣的方式使用IFS

# Set globally the IFS, you'll see it's funny
IFS=,
while read -ra a; do
    a[1]=${a[@]: -2:1}
    echo "${a[*]}"
done < file.csv

全局设置IFS变量使用两次:在read语句中使用一次,以便根据昏迷分割每个字段,并在行echo "${a[*]}""${a[*]}"将展开到由a分隔的数组IFS的字段...这是一个昏迷!

另一件特别之处:你提到了倒数第二个字段,而这正是${a[@]: -2:1}将扩展到的位置(请注意:-2之间的空格),这样你就不必计算你的田地数量。

警告。 csv文件需要一个难以实现的特殊csv解析器。如果字段包含昏迷,这个答案(我猜所有其他不会使用真正的csv解析器的答案)可能会中断,例如,

    1,2,3,4,"a field, with a coma",5

如果要丢弃最后两列,请不要使用cut,而是使用此代码:

IFS=,
while read -ra a; do
    ((${#a[@]}<2)) || continue # skip if array has less than two fields
    a[1]=${a[@]: -2:1}
    echo "${a[*]::${#a[@]}-2}"
done < file.csv