有条件地更改csv中的第二列

有条件地更改csv中的第二列

我有一个如下所示的 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

两种解决方案都首先将行读入数组filenameclass。唯一的区别是bash数组以 开头0awk数组以 开头1

然后,我们循环遍历数组并打印所需的输出。在awk解决方案中,我们需要单独处理第一行,因为与 不同basharray[-1]它不返回最后一个元素。

解决awk方法比较快一点。

相关内容