将文件批量提供给脚本

将文件批量提供给脚本

我有很多文件,命名约定如下:

file1_d, file2_d, file3_d, ...,fileN_d

我想将第一个k文件提供到脚本中作为输入,然后将以下k文件作为第二批提供,依此类推。有没有一种简单的方法可以在 shell 脚本中执行此操作,例如使用数组?

答案1

我假设您想要多次执行该脚本,并且想要批量提供文件作为脚本的命令行参数,每次运行脚本时一次一批。 (您的要求的另一种解释是脚本从标准输入读取文件,并且您希望k一次向其提供文件的串联。下面的代码只需要进行少量更改即可实现这种解释。)

bashshell 中,您可以使用分块提供给脚本的数组。

要创建数组,我们可以这样做

files=( file*_d )

这将扩展通配模式file*_d并将结果名称按字典顺序放入数组中。如果您需要按数字顺序排列文件名,并且数字不是以零填充,那么使用大括号扩展会更容易:

files=( file{1..N}_d )

...其中N是最大数量(实际数量,不是变量,因为bash不理解大括号扩展范围中的变量)。

zshshell 中,您可以使用以下命令创建数组

files=( file<->_d )

...按数字顺序排列它们。下面的代码适用于 和zshshell bash

然后您可以像这样循环调用脚本:

k=10
while [ "${#files[@]}" -gt 0 ]; do
    ./myscript "${files[@]:0:k}"
    files=( "${files[@]:k}" )
done

这将./myscript调用数组k的第一个整体files,然后从数组中删除这些条目。它会一直持续到数组为空为止。

答案2

在 中zsh,您可以使用zargs

autoload zargs
zargs -l ${k?} -- file<->_d(n) -- myscript

使用 bash 和 GNU 实用程序,您可以执行类似的操作:

xargs -r0n"${k?}" -a <(
  shopt -s failglob extglob
  pattern='file+([0123456789])_d' IFS=
  printf '%s\0' $pattern | sort -zV) myscript

globn限定符或sort -V确保文件名按数字排序,以便file10_d在后面file9_dfile1_d例如而不是中间file2_d

如果您想运行其中一些,GNUzargs和 GNUxargs都有一个选项-Pmyscript选项。

答案3

您可以使用 GNU Parallel 来并行执行批处理。

printf '%s\n' file*_d | parallel -j 2 -N "$k" ./myscript

如果您的脚本不从 stdin 读取,而是需要一个参数,您可以使用:::像这样传递它:

parallel -j 2 -N "$k" ./myscript ::: file*_d

-j指定同时运行的作业数(默认为可用核心数)以及-N指定您的情况下的参数限制或批量大小。因此,如果您有-j 2 -N 10脚本,系统将给出每个文件 10 个文件的列表,并且将随时运行两个不同的作业。一旦一个完成,另一个就会开始,直到所有文件被消耗。

如果你不想运行并行作业,你可以通过-j 1

答案4

简单-使用xargs

$ # Let's create 100 files with your naming convention
$ for i in {1..100} ; do touch $(printf "file%03d_d" $i) ; done

$ # Now let's process them in groups of 4 with this script:
$ cat /path/to/some/script.sh
#!/bin/bash
echo called with "$@"

$ ls | LC_ALL=C sort  | xargs -n 4 /path/to/some/script.sh
called with file001_d file002_d file003_d file004_d
called with file005_d file006_d file007_d file008_d
called with file009_d file010_d file011_d file012_d
...
called with file093_d file094_d file095_d file096_d
called with file097_d file098_d file099_d file100_d

使用 C 语言环境前缀sort可能是我的偏执 - 使用任何语言环境/排序选项按照您希望处理文件的顺序对文件进行排序。

如果您想知道,这确实适用于不能完美划分数据集的数字:

$ ls | LC_ALL=C sort  | xargs -n 3 /path/to/some/script.sh
...
called with file091_d file092_d file093_d
called with file094_d file095_d file096_d
called with file097_d file098_d file099_d
called with file100_d

相关内容