我的文件夹中有很多文件,名称类似于00802_Bla_Aquarium_XXXXX.jpg
.现在我需要复制每个第四名文件到子文件夹,说在selected/
.
00802_Bla_Aquarium_00020.jpg <= this one
00802_Bla_Aquarium_00021.jpg
00802_Bla_Aquarium_00022.jpg
00802_Bla_Aquarium_00023.jpg
00802_Bla_Aquarium_00024.jpg <= this one
00802_Bla_Aquarium_00025.jpg
00802_Bla_Aquarium_00026.jpg
00802_Bla_Aquarium_00027.jpg
00802_Bla_Aquarium_00028.jpg <= this one
00802_Bla_Aquarium_00029.jpg
我该怎么做呢?
答案1
使用 zsh,你可以这样做:
n=0; cp 00802_Bla_Aquarium_?????.jpg(^e:'((n++%4))':) /some/place
POSIXly,同样的想法,只是更详细一点:
# put the file list in the positional parameters ($1, $2...).
# the files are sorted in alphanumeric order by the shell globbing
set -- 00802_Bla_Aquarium_?????.jpg
n=0
# loop through the files, increasing a counter at each iteration.
for i do
# every 4th iteration, append the current file to the end of the list
[ "$(($n % 4))" -eq 0 ] && set -- "$@" "$i"
# and pop the current file from the head of the list
shift
n=$(($n + 1))
done
# now "$@" contains the files that have been appended.
cp -- "$@" /some/place
由于这些文件名不包含任何空白或通配符,您还可以执行以下操作:
cp $(printf '%s\n' 00802_Bla_Aquarium_?????.jpg | awk 'NR%4 == 1') /some/place
答案2
在 bash 中,这是一个有趣的可能性,在这里效果很好:
cp 00802_Bla_Aquarium_*{00..99..4}.jpg selected
这绝对是最简短、最有效的答案:没有子 shell,没有循环,没有管道,没有awk
ward 外部进程;只有一个 fork to cp
(无论如何你都无法避免)和一个 bash 括号扩展和 glob(因为你知道你有多少个文件,所以你可以完全摆脱它们)。
答案3
只需使用 bash,您就可以执行以下操作:
n=0
for file in ./*.jpg; do
test $n -eq 0 && cp "$file" selected/
n=$((n+1))
n=$((n%4))
done
该模式./*.jpg
将被 bash 人所述的按字母顺序排序的文件名列表替换,因此它应该适合您的目的。
答案4
如果您知道文件名中不会有换行符,则可以使用:
find . -maxdepth 1 -name "*.jpg" | sort | while IFS= read -r file; do
cp "$file" selected/
IFS= read -r; IFS= read -r; IFS= read -r
done