首页 > 解决方案 > 根据 Bash 中的文件名对文件名进行分组的最佳方法?

问题描述

我有一个包含以下文件的文件夹:

DA-001-car.jpg
DA-001-dog.jpg
DA-001-coffee.jpg
DA-002-house.jpg
DA-003-coffee.jpg
DA-003-cat.jpg
...

我想生成这个(CSV)输出:

SKU, IMAGE
DA-001, "DA-001-car.jpg, DA-001-dog.jpg, DA-001-coffee.jpg"
DA-002, "DA-001-house.jpg"
DA-003, "DA-001-coffee.jpg, DA-001-cat.jpg"

我尝试在 Bash 中对此进行编程:

#!/bin/bash
echo "SKU, FILE" >> tmp.csv
for file in /home/calvin/test/*.jpg
do
    SKU_NAME="${file##*/}"
    echo ${SKU_NAME:0:6}, \"inner for-loop?, ?, ?\" >> tmp.csv
done
uniq tmp.csv output.csv

如您所见,我是编程的菜鸟:)请帮助我,在此先感谢!

标签: bashcsvfor-loopawkuniq

解决方案


如果文件名不包含空格,则可以使用 sed 而不是内部循环:

printf '%s\n' *.jpg \
| cut -f1,2 -d- \
| sort -u \
| while IFS= read -r sku ; do
    echo "$sku",\"$(echo "$sku"* | sed 's/ /, /')\"
done

使用内部循环,您可以切换到printffrom echo。Sed 用于删除结尾的逗号。

printf '%s\n' *.jpg \
| cut -f1,2 -d- \
| sort -u \
| while IFS= read -r sku ; do
    printf %s "$sku, \""
    for f in "$sku"* ; do
        printf '%s, ' "$f"
    done | sed 's/, $//'
    printf '"\n'
done

如果您不想解析ls和 run的输出sort,可以将前缀存储在关联数组中:

#!/bin/bash
declare -A prefix
for jpg in *.jpg ; do
    p1=${jpg%%-*}
    jpg=${jpg#*-}
    p2=${jpg%%-*}
    prefix[$p1-$p2]=1
done

for sku in "${!prefix[@]}" ; do
    printf '%s, "' "$sku"
    for f in "$sku"* ; do
        printf '%s, ' "$f"
    done | sed 's/, $//'
    printf '"\n'
done

推荐阅读