我有很多文件,命名约定如下:
file1_d, file2_d, file3_d, ...,fileN_d
我想将第一个k文件提供到脚本中作为输入,然后将以下k文件作为第二批提供,依此类推。有没有一种简单的方法可以在 shell 脚本中执行此操作,例如使用数组?
我假设您想要多次执行该脚本,并且想要批量提供文件作为脚本的命令行参数,每次运行脚本时一次一批。(您的要求的另一种解释是脚本从标准输入读取文件,并且您希望k一次向其提供文件的串联。下面的代码只需要进行少量更改即可实现这种解释。)
在bashshell 中,您可以使用分块提供给脚本的数组。
要创建数组,我们可以这样做
files=( file*_d )
Run Code Online (Sandbox Code Playgroud)
这将扩展通配模式file*_d并将结果名称按字典顺序放入数组中。如果您需要按数字顺序排列文件名,并且数字不是以零填充,那么使用大括号扩展会更容易:
files=( file{1..N}_d )
Run Code Online (Sandbox Code Playgroud)
...其中N是最大数量(实际数量,不是变量,因为bash不理解大括号扩展范围中的变量)。
在zshshell 中,您可以使用以下命令创建数组
files=( file<->_d )
Run Code Online (Sandbox Code Playgroud)
...按数字顺序排列它们。下面的代码适用于zsh和bashshell。
然后您可以像这样循环调用脚本:
k=10
while [ "${#files[@]}" -gt 0 ]; do
./myscript "${files[@]:0:k}"
files=( "${files[@]:k}" )
done
Run Code Online (Sandbox Code Playgroud)
这将调用./myscript数组k的第一个整体files,然后从数组中删除这些条目。它会一直持续到数组为空为止。
在 中zsh,您可以使用zargs:
autoload zargs
zargs -l ${k?} -- file<->_d(n) -- myscript
Run Code Online (Sandbox Code Playgroud)
使用 bash 和 GNU 实用程序,您可以执行类似的操作:
xargs -r0n"${k?}" -a <(
shopt -s failglob extglob
pattern='file+([0123456789])_d' IFS=
printf '%s\0' $pattern | sort -zV) myscript
Run Code Online (Sandbox Code Playgroud)
例如,globn限定符或sort -V确保文件名按数字排序,以便file10_d位于后面而file9_d不是中间。file1_dfile2_d
如果您想并行运行其中一些调用, GNUzargs和 GNUxargs都有一个选项。-Pmyscript