反转作为参数的文件匹配顺序

反转作为参数的文件匹配顺序

我有一个程序可以按特定顺序读取文件。对于此示例,它们都具有相同的扩展名 txt

{program_name} {input 1...} {output}

我碰巧将输出文件名命名为“a.txt”,因此它是我调用时的第一个结果ls,它显示了输入到此命令的文件的顺序:

{program_name} *.txt

我希望第一个结果显示为最后一个结果。如何颠倒星星匹配的顺序?如果我需要使用管道,正确输入参数以便正确引用任何特殊字符或空格的语法是什么?

答案1

利用zsh

zsh -c 'program *.txt(.^on)'

是模式的修饰符(.^on),使其仅匹配常规文件 (the ),并且将以相反 ( ) 字典顺序( ) 对结果列表进行排序 ( )。zsh*.txt.o^n

这将启动一个非交互式zshshell,该 shell 将以program生成的文件名列表作为命令行参数运行。该命令将正确处理反转参数列表,即使它们在文件名中包含空格或换行符等。

例子:

$ touch {a..d}.txt
$ echo *.txt
a.txt b.txt c.txt d.txt
$ zsh -c 'echo *.txt(.^on)'
d.txt c.txt b.txt a.txt

zsh解:

set --
for fname in *.txt; do
    set -- "$fname" "$@"
done

program "$@"

或者,在例如中使用命名数组bash

args=()
for fname in *.txt; do
    args=( "$fname" "${args[@]}" )
done

program "${args[@]}"

在这两个代码片段中,数组都是根据与*.txt模式匹配的名称构建的。每个名字都被推到数组的前面,所以效果是数组最终以姓氏在前。

在第一个实例中,我们使用位置参数列表作为数组。该代码应该可以在任何sh类似的 shell 中工作。


如果您只需要程序参数列表中的名字位于最后,并且可以让其他名称按照它们扩展的顺序排列,那么下面的代码就可以做到这一点(在任何sh类似的 shell 中):

set -- *.txt
fname=$1
shift
program "$@" "$fname"

或者,使用bash特定语法和命名数组,

args=( *.txt )
program "${args[@]:1}" "${args[0]}"

"${args[@]:1}"将从 element 开始扩展到args数组的所有元素(单独引用)1

再次测试echo

$ args=( *.txt )
$ echo "${args[@]:1}" "${args[0]}"
b.txt c.txt d.txt a.txt

相关内容