我有一个带有类似命名文件的目录,在这种模式中:
00002_930831_fa.ppm 00398_940422_fa.ppm 00714_960530_fa.ppm
00002_930831_fb.ppm 00398_940422_fb.ppm 00714_960530_fb.ppm
00002_931230_fa.ppm 00399_940422_fa.ppm 00714_960620_fa.ppm
00002_931230_fb.ppm 00399_940422_fb.ppm 00714_960620_fb.ppm
00002_940128_fa.ppm 00400_940422_fa.ppm 00715_941201_fa.ppm
00002_940128_fb.ppm 00400_940422_fb.ppm 00715_941201_fb.ppm
00002_940422_fa.ppm 00401_940422_fa.ppm 00715_941205_fa.ppm
00002_940422_fb.ppm 00401_940422_fb.ppm 00715_941205_fb.ppm
00002_940928_fa.ppm 00402_940422_fa.ppm 00716_941201_fa.ppm
00002_940928_fb.ppm 00402_940422_fb.ppm 00716_941201_fb.ppm
我需要做的是删除例如除00002样本的两个实例之外的所有实例(并不重要),以便我以00002_930831_fa.ppm
和{{为例离开1}}。问题是我需要为所有样本,00003,00004等完成此操作。我需要为每个样本留下两个文件。
我已经尝试00002_930831_fb.ppm
,但我不确定如何解决我的病情。
这可以通过简单的管道命令来解决,还是我必须用bash脚本来解决它?
答案 0 :(得分:3)
只需使用head
或tail
过滤您的文件名列表:
ls 00002_* | tail -n +3 | xargs rm
答案 1 :(得分:2)
创建一个包含所有匹配文件名的数组,然后使用substring参数扩展运算符将前两个元素作为参数传递给rm
。
while read -r sample; do
matching_files=( ${sample}_* )
# To make sure at least two files survive:
(( ${#matching_files[@]} > 2 )) && rm "${matching_files[@]:2}"
done < samples.txt
答案 2 :(得分:1)
使用关联数组:
#!/bin/bash
[[ BASH_VERSINFO -ge 4 ]] || {
echo "You need Bash 4.0 or newer to run this script." >&2
exit 1
}
declare -A COUNTER=()
for A in *.ppm; do
IFS=_ read I __ <<< "$A"
(( ++COUNTER[$I] > 2 )) && rm "$A"
done
模拟:
Skip 00002_930831_fa.ppm
Skip 00002_930831_fb.ppm
rm 00002_931230_fa.ppm
rm 00002_931230_fb.ppm
rm 00002_940128_fa.ppm
rm 00002_940128_fb.ppm
rm 00002_940422_fa.ppm
rm 00002_940422_fb.ppm
rm 00002_940928_fa.ppm
rm 00002_940928_fb.ppm
Skip 00398_940422_fa.ppm
Skip 00398_940422_fb.ppm
Skip 00399_940422_fa.ppm
Skip 00399_940422_fb.ppm
Skip 00400_940422_fa.ppm
Skip 00400_940422_fb.ppm
Skip 00401_940422_fa.ppm
Skip 00401_940422_fb.ppm
Skip 00402_940422_fa.ppm
Skip 00402_940422_fb.ppm
Skip 00714_960530_fa.ppm
Skip 00714_960530_fb.ppm
rm 00714_960620_fa.ppm
rm 00714_960620_fb.ppm
Skip 00715_941201_fa.ppm
Skip 00715_941201_fb.ppm
rm 00715_941205_fa.ppm
rm 00715_941205_fb.ppm
Skip 00716_941201_fa.ppm
Skip 00716_941201_fb.ppm
注意:首先在一些虚拟文件上测试它。
来想一想:
IFS=_ read I __ <<< "$A"
可以
I=${A%%_*}
答案 3 :(得分:0)
使用bash版本4:
declare -A files
for f in *ppm; do
files[${f%%_*}]+="$f "
done
for i in "${!files[@]}"; do
set -- ${files[$i]}
shift 2
(($# > 0)) && echo rm $*
done
如果您对选择要删除的正确文件感到满意,请删除echo
。
如果有任何带有空格的文件名,则无效。