我有一个包含多个列的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文件中的另一列。哪个更容易实现。提前感谢您的帮助。
答案 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)
纯bash解决方案,以有趣的方式使用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