У меня есть файл 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
До сих пор я попытался только видеть, могу ли я изменить ne класс на другого, но без успеха:
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
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
решение немного быстрее.