我有一个文件夹,里面有很多 shell 脚本来配置我的服务器。
我的主脚本被命名为“setup.sh”,所有其他脚本被命名为 0.script.sh、1.script.sh... 更一般地说是 N.SCRIPT_NAME.sh,其中 N 是执行编号。
因此,我想列出该文件夹中的所有 shell 脚本,并按照 N 个数字指定的顺序执行它们。
答案1
可能有一种更简单的方法可以使用 zsh 按顺序获取文件名,但这是 bash 中的一种强力方法:
for script in ?.script*.sh ??.script*.sh ???.script*.sh ????.script*.sh
do
printf "Executing script: %s\n" "$script"
./"$script"
done
这假设您的脚本不超过 9999 个,或者更准确地说,文件名前缀部分中的数字(字符)不超过 4 个。
它还假设前缀是编号的- 它将要选择名为 例如 的脚本(go.script_X.sh
如果您有的话)。解决办法那,将 替换?
为[0-9]
:
for f in [0-9].script*.sh [0-9][0-9].script*.sh ...
shell 的自然通配机制将按字母顺序对结果文件名进行排序,这也会导致它们按数字顺序排序。各种文件名以递增的比例拼写,因此“9”排在“101”等之前。
在 zsh 中,按前缀的数字顺序 glob 文件名:
for script in *.script*.sh(oe_'REPLY=${REPLY%%.*}'_n)
do
printf "Executing script: %s\n" "$script"
./"$script"
done
通配扩展首先拾取所有*.script*.sh
文件,然后o
使用表达式对它们进行排序(排序)e
,该表达式通过尽可能多地剥离“点后跟任何内容”来提取前缀,并使用n
数字排序。
答案2
如果文件名很简单(没有空格,没有换行符,没有 ls 需要用 a 编码的字符?
),那么,也许!! ,你可以摆脱:
IFS=$' \t\n'; for s in $(ls -v folder/*.script.sh); do printf '%s\n' "$s"; done
在这种情况下,ls
将按版本号排序-v
(与数值非常相似)。
但一般来说,解析(处理)的输出是一个坏主意ls
。
这个更好:
shopt -s nullglob
for s in folder/?{,?{,?{,?}}}.script.sh
do printf '%s\n' "$s"
done
.script.sh
它将按每个字符最多四个字符(数字)列出(按字母顺序,如果前面的字符只是数字,则相当于数字顺序)。
这个想法是大括号扩展发生在之前路径名扩展。这大括号扩展将转换并扩展?{,?{,?{,?}}}.script.sh
为
?.script.sh ??.script.sh ???.script.sh ????.script.sh
然后,路径名扩展将找到与每个模式匹配的所有文件,并依次对每个模式进行排序。
如果以上选项都不能解决问题,您将需要使用sort
:
printf '%s\n' *.script.sh | sort -n | xargs echo
如果有folder
前缀,情况会变得更加复杂:
printf '%s\n' folder/*.script.sh | sort -n -k 1.8 | xargs echo
其中8是单词中的字符(字节)数folder
,后面/
加一(1)。
您需要用 替换echo
来sh
执行每个脚本。如果没有文件名包含换行符,此方法将正常工作。
如果文件名可能包含换行符,请使用以下命令:
printf '%s\0' folder/*.script.sh | sort -zn -k 1.8 | xargs -0 -I{} echo '{}'
再次,将 替换echo
为sh
(或bash
) 以执行脚本。