iKn*_*All 5 command-line awk csv text-processing
我有一个 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
Run Code Online (Sandbox Code Playgroud)
其中第一列是路径,第二列是类。我想有条件地更改第二列。在伪代码中,我想要类似的东西:
If second column "four" change it to the next row's class
Run Code Online (Sandbox Code Playgroud)
到目前为止,我只是想看看我是否可以将 ne 类更改为另一个类,但没有成功:
awk '{ if ($2 == "zero") $2="one"; print $0 }' train.csv > new_file.csv
Run Code Online (Sandbox Code Playgroud)
给我同样的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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
等效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
Run Code Online (Sandbox Code Playgroud)
两种解决方案首先将行读入数组filename和 class. 唯一的区别是bash数组以 开头0,awk数组以1.
然后,我们遍历数组并打印所需的输出。在awk解决方案中,我们需要单独处理第一行,因为与 in 不同bash,array[-1]它不返回最后一个元素。
该awk解决方案是一个有点快。