如何在bash中创建动态命令?

时间:2019-09-19 23:28:32

标签: linux bash shell sh

我想在运行程序的变量中有一个命令,并根据退出文件的数量(每次要处理一个新文件)为其指定输出文件名。

这是我所拥有的:

export MY_COMMAND="myprogram -o ./dir/outfile-0.txt"

但是,我希望每次执行outfile时,使这个MY_COMMAND的数目增加。您可能假设myprogram在下一次调用之前足够早地创建了文件。因此,可以从目录./dir/中存在的文件数中检索该数。我无权更改程序本身或使用MY_COMMAND

谢谢。

3 个答案:

答案 0 :(得分:2)

鉴于您无法更改myprogram-其-o选项将始终写入命令行中给定的文件,并假设您的控件正在运行MY_COMMAND,因此您无法更改MY_COMMAND的调用方式,您仍然可以控制MY_COMMAND

对于此答案的其余部分,我将把名称MY_COMMAND更改为callprog,主要是因为它更易于输入。

您可以像在示例callprog中那样将export callprog="myprogram -o ./dir/outfile-0.txt"定义为变量,但是您可以编写一个shell脚本并命名那个 callprog和一个Shell脚本几乎可以完成您想要的任何事情。

因此,您有一个充满outfile-<num>.txt个文件的目录,并且想要输出到下一个非冲突的outfile-<num+1>.txt

您的shell脚本可以通过列出文件,仅切出数字,对它们进行排序然后取最大数字来获取数字。

如果我们在dir中有这些文件:

outfile-0.txt
outfile-1.txt
outfile-5.txt
outfile-10.txt

ls -1 ./dir/outfile*.txt产生列表

./dir/outfile-0.txt
./dir/outfile-1.txt
./dir/outfile-10.txt
./dir/outfile-5.txt

(使用outfile.txt表示,即使有其他文件的名称不是 outfile ,这也将起作用)
通过流编辑器sed用管道将数字刮掉……捕获数字并仅保留该部分:

ls -1 ./dir/outfile*.txt | sed -e 's:^.*dir/outfile-\([0-9][0-9]*\)\.txt$:\1:'

(我使用冒号:而不是标准斜杠/,所以我不必在dir/outfile中转义目录分隔符)

现在,您只需要选择最高的号码即可。对数字进行排序并排在最前面

| sort -rn | head -1

-n进行排序是数字式的,而不是按字母顺序排序,-r则相反,因此最高的数字将是 first ,而不是最后。

将它们放在一起,将列出文件,编辑名称,仅保留数字部分 ,排序并获得第一个条目。您想要将其分配给一个变量以使用它,所以它是:

high=$(ls -1 ./dir/outfile*.txt | sed -e 's:^.*dir/outfile-\([0-9][0-9]*\)\.txt$:\1:' | sort -rn | head -1)

在shell(我正在使用bash)中,您可以对此进行数学运算,$[high + 1],因此,如果 high 为10,则表达式生成11
您可以将其用作文件名的数字部分。

然后,整个shell脚本只需要在文件名中使用该数字即可。就是这样,其中的行被打断以提高可读性:

#!/bin/sh

high=$(ls -1 ./dir/outfile*.txt \
       | sed -e 's:^.*dir/outfile-\([0-9][0-9]*\)\.txt$:\1:' \
       | sort -rn | head -1)

echo "myprogram -o ./dir/outfile-$[high + 1].txt"

当然您不会 echo 我的程序,只需运行它即可。

答案 1 :(得分:0)

您可以在.bashrc下的bash函数中执行此操作,方法是使用wc获取dir中的文件数,然后将1加到结果中

yourfunction () {
dir=/path/to/dir
filenum=$(expr $(ls $dir | wc -w) + 1)
myprogram -o $dir/outfile-${filenum}.txt
}

这应该获取$ dir中的文件数,并在该数后附加1以获取文件名所需的数。如果将其放在.bashrc中或.bash_aliases和源.bashrc下,则它应该像其他任何shell命令一样工作

答案 2 :(得分:0)

您可以尝试导出功能以使MY_COMMAND运行。

next_outfile () {
    my_program -o ./dir/outfile-${_next_number}.txt
    ((_next_number ++ ))
}

export -f next_outfile
export MY_COMMAND="next_outfile" _next_number=0

这依赖于将“专用”全局变量_next_number初始化为0且未经其他修改。