我有一个 python 脚本,它采用一堆文本文件所在的路径来以某种方式处理它们。由于文件太多,我想使用 bash 脚本批量传递路径上的一些文件,比如一次 100 个。有没有一种简单的方法可以做到这一点。例如我的脚本目前是
python application.py -fp [path to all files]
我可以做一个 bash 脚本吗?
python application.py -fp [file-1:file-100]
并在下一个循环中
python application.py -fp [file-101:file-200]
等等?
编辑:
我用 bash 尝试了 Stephane 解决方案,我认为它几乎可以工作,但我仍然无法获取文件的子集
我这样做是为了从 bash 脚本的参数中获取路径
set -- "$fp*.txt"
echo "${@}"
结果是
../../files_test/pair/*.txt
这是正确的,因为这是我需要获取的文件的路径。但后来我这样做了
files=${@:1:2}
echo $files
只是为了测试我是否可以获得第一个文件,但它会回显目录中所有文件的列表。我错过了什么吗?
编辑2:
没关系。我意识到我在做
set -- "$fp*.txt"
代替
set -- $fp*.txt
现在可以了。
答案1
使用 GNUxargs
和支持进程替换的 shell(ksh、bash、zsh),您可以执行以下操作:
xargs -r0 -n100 -a <(printf '%s\0' ./*) python application.py -fp
例子:
$ xargs -r0n4 -a <(printf '%s\0' {1..20}) echo
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
如果没有进程替换,您还可以执行以下操作:
printf '%s\0' ./* | xargs -r0 -n100 -python application.py -fp
但这意味着application.py
的 stdin 将是您可以通过基本上手动实现进程替换来解决的/dev/null
系统上的问题:/dev/fd/xxx
{
printf '%s\0' ./* |
xargs -a /dev/fd/3 3<&0 <&4 4<&- -r0 -n100 -python application.py -fp
} 4<&0
和zsh
:
autoload zargs
zargs -l 100 ./* -- python application.py -fp
例子:
$ zargs -l4 {1..20} -- echo
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
您也可以随时执行以下操作(ksh93/bash/zsh):
set -- ./*
while (($# > 0)); do
python application.py -fp "${@:1:100}"
shift "$(($# >= 100 ? 100 : $#))"
done
例子:
$ set -- {1..20};while (($#>0));do echo "${@:1:4}";shift "$(($#>4?4:$#))";done
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
如果您的文件实际上被称为file-1
, file-2
... 您可能需要使用zsh
及其n
(用于数字排序)glob 限定符来对要按数字排序的文件列表:
zargs -l 100 ./*(n) -- python application.py -fp
sort -zV
或者在以下输出上使用 GNU (用于版本排序) printf '%s\0'
:
xargs -r0 -n100 -a <(printf '%s\0' ./* | sort -zV) python application.py -fp