我有一个如下所示的 csv 文件:
data/train/4/36280.png,four
data/train/2/10317.png,two
data/train/2/57890.png,two
data/train/1/53448.png,one
data/train/8/58233.png,eight
data/train/4/23599.png,four
data/train/2/35051.png,two
data/train/1/12323.png,one
data/train/9/18562.png,nine
data/train/8/46629.png,eight
data/train/7/1746.png,seven
第一列是路径,第二列是类。我想有条件地更改第二列。在伪代码中我想要类似的东西:
If second column "four" change it to the next row's class
到目前为止,我只是想看看是否可以将一个类更改为另一个类,但没有成功:
awk '{ if ($2 == "zero") $2="one"; print $0 }' train.csv > new_file.csv
给我相同的 csv。
基本上我想要一个能给我以下输出 csv 的脚本:
data/train/4/36280.png,seven
data/train/2/10317.png,four
data/train/2/57890.png,two
data/train/1/53448.png,two
data/train/8/58233.png,one
data/train/4/23599.png,eight
data/train/2/35051.png,four
data/train/1/12323.png,two
data/train/9/18562.png,one
data/train/8/46629.png,nine
data/train/7/1746.png,eight
答案1
bash
解决方案:
readarray -t filename < <(cut -d ',' -f1 train.csv)
readarray -t class < <(cut -d ',' -f2 train.csv)
for (( i=0; i<${#filename[@]}; i++ )); do
printf '%s,%s\n' "${filename[$i]}" "${class[$((i-1))]}";
done > new_file.csv
等效awk
解决方案:
awk -F, '
{
filename[NR]=$1
class[NR]=$2
}
END {
OFS=","
print filename[1],class[NR]
for (i=2;i<=NR;i++) {
print filename[i],class[i-1]
}
}
' train.csv > new_file.csv
两种解决方案都首先将行读入数组filename
和 class
。唯一的区别是bash
数组以 开头0
,awk
数组以 开头1
。
然后,我们循环遍历数组并打印所需的输出。在awk
解决方案中,我们需要单独处理第一行,因为与 不同bash
,array[-1]
它不返回最后一个元素。
解决awk
方法比较快一点。