我有一个关键字列表keywords.txt
cat & mouse
dog
mouse
以及文件中的一长串图像文件images.txt
8284,cat-mouse.jpg001
8286,cat-mouse.jpg003
8285,cat-mouse.jpg002
50,mouse.jpg004
52,mouse.jpg003
1000,dog.jpg003
1003,dog.jpg002
1002,dog.jpg001
51,mouse.jpg002
53,mouse.jpg001
我需要图像列表如下所示
8284,cat-mouse.jpg001
8285,cat-mouse.jpg002
8286,cat-mouse.jpg003
1000,dog.jpg001
1002,dog.jpg002
1003,dog.jpg003
50,mouse.jpg001
51,mouse.jpg002
52,mouse.jpg003
53,mouse.jpg004
每个关键字之前的图像编号,
需要采用正确的数字顺序,并且 jpgxyz 值需要以 001 开头,依此类推,但是关键字列表优先,这就是为什么猫和老鼠 > 狗 > 老鼠。关键字列表还包含图像文件不喜欢的字符,& ! ,
并且关键字可以相似,例如另一个关键字可能是dog2
不应该组合的。
答案1
与 @Freddy 关于变换的假设类似。
OUTPUT=output.txt
IMAGES=images.txt
KEYS=keywords.txt
if [ -f $OUTPUT ]; then rm $OUTPUT; fi
while read KEY; do
KEY=$(echo "$KEY" | sed -E -e 's/[)(&!,]/ /g ; s/ +/-/g')
echo "key is ,$KEY."
grep -Po "[0-9]+,$KEY\.jpg" $IMAGES | sort -k1 -n -t, | cat -n | while read N F
do
echo $F$(printf "%03g" $N) | tee -a $OUTPUT
done
echo
done < $KEYS
产量
key is ,cat-mouse.
8284,cat-mouse.jpg001
8285,cat-mouse.jpg002
8286,cat-mouse.jpg003
key is ,dog.
1000,dog.jpg001
1002,dog.jpg002
1003,dog.jpg003
key is ,mouse.
50,mouse.jpg001
51,mouse.jpg002
52,mouse.jpg003
53,mouse.jpg004
500,mouse.jpg005
到 STDOUT,但空行和键不会写入输出文件
最后sort -k1 -n -t,
对每个键上的输出进行数字排序,这样你就不会得到
500,mouse.jpg001
50,mouse.jpg002
51,mouse.jpg003
52,mouse.jpg004
53,mouse.jpg005
编辑
images.txt
要运行它,您可以将代码复制/粘贴到在包含和的目录中打开的终端中keywords.txt
。输出将被写入到output.txt
.根据您的需要更改这些名称。
否则,将其复制到文本文件并保存到文件所在的位置;使其可执行 ( chmod +x whateverYouCalledIt
),然后您可以通过键入从命令行访问它./whateverYouCalledIt
如果您执行与上面相同的操作,但保存到 $PATH 中的目录,那么您可以在任何地方运行它whateverYouCalledIt
喜欢这
还()
添加到要替换的字符列表中-
答案2
关键字转换的假设如下:
- 将
&
,!
和替换,
为空字符串 - 将空格字符替换为
-
- 将多个替换
-
为一个-
您必须sed
相应地修改替换内容。
#!/bin/bash
# read keywords linewise
while IFS= read -r keyword; do
# replace '&', '!', ',' with empty string ''
# replace ' ' with '-'
# replace multiple '-' with one '-'
kw=$(echo "$keyword" | sed 's/[&!,]//g; s/ /-/g; s/-\+/-/g')
echo "keyword: \"$keyword\" -> \"$kw\""
count=0
# filter input file by keyword without jpg index and sort numeric
while IFS= read -r line; do
# write sorted lines with new jpg index
printf '%s%.3d\n' "$line" $((++count)) >> images.txt.new
done < <(grep -o '[0-9]\+,'"$kw"'\.jpg' images.txt | sort -n)
done < keywords.txt
笔记:
- 新图像列表的输出附加到
images.txt.new
。您必须在下次运行之前删除该文件。 - 不匹配的关键字/错误的关键字转换将导致输出丢失/错误。
输出(仅查看关键字转换):
$ ./script.sh
keyword: "cat & mouse" -> "cat-mouse"
keyword: "dog" -> "dog"
keyword: "mouse" -> "mouse"
答案3
如果您需要,我可以添加一些评论。
第一种方法 - 仅呆呆地看:
#!/bin/bash
gawk -F'[,.]' '
FNR == NR {
gsub(/[&!, )(]+/, "-")
keyword_arr[i++] = $0
}
FNR != NR {
image_arr[$2][$1]
}
END {
PROCINFO["sorted_in"] = "@ind_num_asc"
for(i in keyword_arr) {
keyword = keyword_arr[i]
jpg_cnt = 0
for(image_num in image_arr[keyword]) {
printf("%d,%s.jpg%03d\n", image_num, keyword, ++jpg_cnt)
}
}
}' keywords.txt images.txt
第二种方法 - 使用包含每个关键字的文件的辅助目录:
#!/bin/bash
aux_dir='auxiliary_dir'
mkdir -p "$aux_dir"
gawk -F'[.,]' -v aux_dir="$aux_dir" '{
print $1","$2 > aux_dir"/"$2
}' images.txt
sed -r 's/[!&, )(]+/-/' keywords.txt | while read keyword;
do
sort -n "${aux_dir}/${keyword}" | gawk '{printf("%s.jpg%03d\n", $0, NR) }'
done
# The 'echo' is added for safety while testing.
# The auxiliary directory is no longer needed, so can be removed
echo rm -r "${aux_dir}"
输出:
8284,cat-mouse.jpg001
8285,cat-mouse.jpg002
8286,cat-mouse.jpg003
1000,dog.jpg001
1002,dog.jpg002
1003,dog.jpg003
50,mouse.jpg001
51,mouse.jpg002
52,mouse.jpg003
53,mouse.jpg004