例如我有文件:
file0.txt
file1.txt
file2.txt
....
file100.txt
我想在 bash 中复制 5 个文件,这将产生结果:
file0.txt
file19.txt
file39.txt
file59.txt
file79.txt
编辑。搞砸了计数应该是这样的:
file0.txt
file20.txt
file40.txt
file60.txt
file80.txt
因此文件是均匀间隔采样的。希望有一些很酷的oneliner。
答案1
请注意,大括号扩展不是通配符,无论结果中的单词是否引用实际文件,它都会扩展。如果您只想复制那些实际存在的文件,您可以这样做:
shopt -s failglob extglob
cp file@(0|[1357]9).txt /path/to/destination/
在 中,您可以通过附加(对于 nullglob)限定符zsh
来强制对任意字符串进行通配解释。(N)
cp file{0,{1..79..20}}.txt(N) /path/to/destination/
我们需要 nullglob 来避免错误任何的全局扩展无法匹配任何内容,但这意味着如果它们都不匹配,cp /path/to/destination/
则将运行。那么严格来说,应该是:
(){ if (($#)) cp $@ /path/to/destination; } file{0,{19..79..20}}.txt(N)
或者使用以下方法(0|19|...)
动态构造一个 glob:
() { cp file(${(~j[|])@}).txt /path/to/destination; } 0 {19..79..20}
这次没有 nullglob,所以你会得到正确的结果不匹配如果未找到文件,则会出现错误。
要每 20 到 5 个按数字排序的列表复制一个file<digits>.txt
:
() {
printf -v argv '%s%20$.0s' $argv
cp -- $argv[1,5] /path/to/destination
} file<->.txt(n)
答案2
bash 中的大括号扩展支持以下格式的步骤{<start>..<end>..<step>}
:
$ echo file{0..100..19}.txt
file0.txt file19.txt file38.txt file57.txt file76.txt file95.txt
虽然看起来你需要不规则的间距:
$ echo file0.txt file{19..100..20}.txt
file0.txt file19.txt file39.txt file59.txt file79.txt file99.txt
答案3
您提供的一组文件名(数字)中没有有用的模式,因此您可以期望的最简单的“一行”是:
cp file0.txt file19.txt file39.txt file59.txt file79.txt destination_dir/
我曾考虑过将间隔 0..100 除以 5,或者为每个增量添加 20,但是都没有给出您指定的文件集。
如果您不太确定想要哪一组文件,那么可以获取完整的 101 个文件集,将其除以所需的文件数量,然后沿着集合递增,选出目标文件。这是一个例子bash
:
files=(*) # Assume current directory
samples=5 # How many required
total=${#files[@]}; echo total=$total # Number of files
interval=$(( total/samples )); echo interval=$interval # Integer arithmetic
for ((i=0; i<samples; i++))
do
fileNo=$((i*interval)) # Which sample
echo i=$i, fileNo=$fileNo, file=${files[$fileNo]} # Chosen sample
## cp -- "${files[$fileNo]}" destination_dir/ # Copy the file
done
输出
total=101
interval=20
i=0, fileNo=0, file=file0.txt
i=1, fileNo=20, file=file26.txt
i=2, fileNo=40, file=file44.txt
i=3, fileNo=60, file=file62.txt
i=4, fileNo=80, file=file80.txt
正如您所看到的,所选文件与您所需的集不匹配,分别是file0.txt
、file26.txt
、file44.txt
、file64,txt
和file80.txt
。
答案4
如果您的系统已jot
安装,它可以执行以下操作:
$ jot -w 'cp "file%d.txt" "destination/"' 5 0 100
该命令指示jot
生成和5
之间的数字(含)。每个数字都在打印规范的部分中被替换,因此,例如,如果您需要前导零,则可以使用0
100
%d
-w
... -w 'cp "file%03d.txt" ...
检查这些命令,如果它们看起来像您想要执行的操作,则向上箭头并将其通过管道传输到sh
.
$ jot -w 'cp "file%d.txt" "destination/"' 5 0 100
cp "file0.txt" "destination/"
cp "file25.txt" "destination/"
cp "file50.txt" "destination/"
cp "file75.txt" "destination/"
cp "file100.txt" "destination/"
$ jot -w 'cp "file%d.txt" "destination/"' 5 0 100 | sh