带括号的Linux shell脚本命令变量,用于范围选择

z9smfwbn  于 2023-10-23  发布在  Shell
关注(0)|答案(1)|浏览(149)

我正在编写一个shell脚本,它根据文件名创建一个文件列表,但我需要使用一个指定的范围,使用方括号。例如:{30..35}
不知何故,shell脚本不接受命令中的括号,作为我的脚本的一个例子:

InicialMin=$(date -d "-5 minutes" +%M)
FinalMin=$(date +%M)
MinRange="${MinInicial}..${MinFinal}" # Outputs for example 30..35

Results=$(ls -lrth /path/to/my/directory/SOMEFILES_20230922{$MinRange}.log | wc -l)
echo "Files found: ${Results}"

在shell中执行命令行,运行正常:

ls -lrth /path/to/my/directory/SOMEFILES_20230922{35..40}.log | wc -l
153

但是当我执行我的shel脚本,里面有命令时,它说:

ls: cannot access /path/to/my/directory/SOMEFILES_20230922{35..40}.log: No such file or directory

我需要做的文件名的基础上上市,而不是修改时间(发现)。
我尝试了各种各样的转义脚本上的“{}”字符,它没有工作。

在shell脚本中是否有方法执行以下命令?

ls -lrth /path/to/my/directory/SOMEFILES_20230922{$MinRange}.log

尝试:

Results=$(ls -lrth /path/to/my/directory/SOMEFILES_20230922\{$MinRange\}.log | wc -l)
Results=$(ls -lrth /path/to/my/directory/SOMEFILES_20230922'{'$MinRange'}'.log | wc -l)
Results=$(ls -lrth /path/to/my/directory/SOMEFILES_20230922{{$MinRange}}.log | wc -l)
izkcnapc

izkcnapc1#

回答您的问题:
MinRange="${MinInicial}..${MinFinal}" # Outputs for example 30..35
.是否有办法在shell脚本中执行以下命令?
ls -lrth /path/to/my/directory/SOMEFILES_20230922{$MinRange}.log
不能,你也不能在命令行上这样做,因为括号展开在**变量展开之前发生,你需要做其他的事情。
{35..40}不等于{${MinInicial}..${MinFinal}},也不等于{$MinRange}
当我在shell中执行命令行时,它工作正常
错误,成功的命令行(无变量)与失败的命令行(有变量)不一样。只有这三个表达式中的第一个才能做你想要的。
如果你的shell有readarray,那么获取一个文件名数组的方法是:

readarray -td '' files < <(
    for (( i=MinInicial; i<=MinFinal; i++ )); do
        file="/path/to/my/directory/SOMEFILES_20230922${i}.log"
        [[ -f "$file" ]] && printf '%s\0' "$file"
    done
)

或者这样(因为你的文件名不包含换行符):

IFS=$'\n' read -r -d '' -a files < <(
    for (( i=MinInicial; i<=MinFinal; i++ )); do
        file="/path/to/my/directory/SOMEFILES_20230922${i}.log"
        [[ -f "$file" ]] && printf '%s\n' "$file"
    done
    printf '\0'
)

然后你可以循环遍历数组来对文件做任何你喜欢的事情:

echo "Files found: ${#files[@]}"
for file in "${files[@]}"; do
    echo "$file"
done

或者只处理上面第一个循环中找到的每个文件。
顺便说一下,如果你再次考虑将ls的输出管道到wc或任何其他命令,请阅读https://mywiki.wooledge.org/ParsingLs,并在脚本中注意:

InicialMin=$(date -d "-5 minutes" +%M)
FinalMin=$(date +%M)
MinRange="${MinInicial}..${MinFinal}" # Outputs for example 30..35

你正在填充InicialMinFinalMin,但随后尝试使用不同的名称,MinInicialMinFInalhttp://shellcheck.net会在脚本中告诉你这个问题和其他问题。

相关问题