Linux 如何在bash中创建动态命令?
我希望在一个变量中有一个命令,该变量运行一个程序,并根据文件出口的数量指定该程序的输出文件名(每次处理一个新文件) 以下是我所拥有的:Linux 如何在bash中创建动态命令?,linux,bash,shell,sh,Linux,Bash,Shell,Sh,我希望在一个变量中有一个命令,该变量运行一个程序,并根据文件出口的数量指定该程序的输出文件名(每次处理一个新文件) 以下是我所拥有的: export MY_COMMAND=“myprogram-o./dir/outfile-0.txt” 但是,每次执行我的_命令时,我想使这个输出文件的数量增加。您可以假设myprogram在下一次调用之前很快创建了文件。因此,可以从目录/dir/中存在的文件数量中检索该数字。我无权更改我的程序本身或使用MY_命令 提前感谢。您可以在.bashrc下的bash函数
export MY_COMMAND=“myprogram-o./dir/outfile-0.txt”
但是,每次执行我的_命令时,我想使这个输出文件
的数量增加。您可以假设myprogram
在下一次调用之前很快创建了文件。因此,可以从目录/dir/
中存在的文件数量中检索该数字。我无权更改我的程序本身或使用MY_命令
提前感谢。您可以在.bashrc下的bash函数中执行此操作,方法是使用wc获取目录中的文件数,然后在结果中添加1
yourfunction () {
dir=/path/to/dir
filenum=$(expr $(ls $dir | wc -w) + 1)
myprogram -o $dir/outfile-${filenum}.txt
}
这将获得$dir中的文件数,并在该数后附加1以获得文件名所需的数字。如果您将它放在.bashrc或.bash_别名和source.bashrc下,那么它应该像任何其他shell命令一样工作,因为您不能更改myprogram
-它的-o
选项将始终写入命令行上给定的文件,并且假设您无法控制的东西正在运行MY_命令
,因此您无法更改调用MY_命令
的方式,您仍然可以控制MY_命令
对于这个答案的其余部分,我将把名称MY_COMMAND
改为callprog
,主要是因为它更容易键入
您可以将callprog
定义为变量,如示例中的export callprog=“myprogram-o./dir/outfile-0.txt”
,但您可以编写一个shell脚本并命名为callprog
,shell脚本可以执行您想要的任何操作
因此,您有一个满是outfile-.txt
文件的目录,并且希望输出到下一个非冲突的outfile-.txt
您的shell脚本可以通过列出文件、只剪切数字、对它们进行排序,然后取最大的数字来获取数字
如果我们在目录中有这些文件
:
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:'
(我使用冒号:
而不是标准的斜杠/
,因此我不必在目录/outfile
中转义目录分隔符)
现在你只需要选择最高的数字。对数字进行排序,然后取顶部
| sort -rn | head -1
使用-n
进行排序是数字排序,而不是词法排序,-r
反向排序,因此最高的数字将是第一个,而不是最后一个
把它们放在一起,这将列出文件,编辑名称,只保留数字部分,排序,只获得第一个条目。您希望将其分配给变量以使用它,因此:
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"
当然你不会回显我的程序,你只需要运行它。你可以尝试导出一个函数,让MY\u命令运行
next_outfile () {
my_program -o ./dir/outfile-${_next_number}.txt
((_next_number ++ ))
}
export -f next_outfile
export MY_COMMAND="next_outfile" _next_number=0
这依赖于一个“私有”全局变量\u next\u number
被初始化为0,并且没有进行其他修改。为了澄清。。。您不能修改myprogram
,也不能更改调用myu命令的方式,但您可以为myu命令提供新的定义?我还假设您不局限于导出MY_命令=…
——您可以根据需要编写一个复杂的shell脚本,并将其命名为MY_命令,或者从MY_命令调用它。您是对的,答案是有效的,尽管我没有给出更多详细信息,但是命令${MY u命令}正在与其他一些我无法控制的参数一起使用。因此,对于您的解决方案,我应该通过“$@”
将它们传递给程序,这很好,但如果输入有双引号,则可能会导致问题。无论如何,谢谢。这有很多答案:1)创建一个索引文件,2)搜索最后一个,然后增加数量,3)计数文件,添加+1。。。等等你已经试过什么了吗?请告诉我们你已经尝试了什么!我写了一个脚本,它可以找出目录中的文件数,然后运行这个命令。这个函数是个好主意expr
是不必要的;改用$(…+1))
。分析ls
的输出是错误的。sed
可以写为:.file-\([0-9]\+\)\.tx..
或.file-\([1-9][0-9]*\)\.tx..
;)无论如何,答案是正确的。