我正在 bash 脚本中对大文件执行多个命令。为了监控进度,我使用 pv 命令。
示例命令可能如下所示
cat $IN_FILE | pv -w 20 -s $(du -sb $IN_FILE | awk '{print $1}') | grep ...
该脚本包含多个具有相似结构的命令,而不必一次又一次地在所有这些命令上使用相同的前缀,我为进度监视部分定义了一个函数作为速记。 (注意:fSize 和 fSize Sum 函数包装了上例中的 du 命令部分,其中 fSizeSum 返回两个文件的大小之和,fSize 返回一个文件的大小):
function prog()
{
local __size
if [[ $2 ]]
then
__size=$(fSizeSum $1 $2)
else
__size=$(fSize $1)
fi
echo "cat $1 | pv -w 20 -s ${__size}"
}
实际上,这种方法已经稍微缩短了命令。我现在可以像这样执行上面的示例:
eval "$(prog $IN_FILE) | grep ..."
仍然困扰我的是,我现在必须引用每一行并使用 eval。我宁愿使用函数“prog”,就像它是常规 shell 命令一样,即:
prog $IN_FILE | grep ...
到目前为止,我所有修改函数以作为管道命令链中的前缀的尝试都失败了。
有什么方法可以使自定义的 bash 脚本函数像常规 bash 命令一样运行并将其放在管道链前面吗?如果无法使用函数来实现此目的,是否还有其他方法可以实现此目标 - 例如在脚本中定义本地别名?
答案1
在您的函数定义中,我建议替换:
echo "cat $1 | pv -w 20 -s ${__size}"
只是:
cat $1 | pv -w 20 -s ${__size}
eval
这样,函数本身将执行这段代码,而不需要在调用者中进行调用。
答案2
pv
行为就像cat
您将文件作为参数传递一样,这样您甚至不需要传递 -s。
所以你可以这样做:
pv -w 20 $IN_FILE | grep ...