在 bash 脚本中使用模板 file{1..n} 获取带有 ls 的文件列表
Get list of files with `ls` using template `file{1..n}` in bash script
我可以使用模板在我的目录中创建一些文件:
touch file{1..3}
要获取文件列表,我使用命令:
ls file{1..3}
输出:
file1 file2 file3
但是当我尝试在 bash 脚本中对变量使用相同的命令时:
#/bin/bash
a=1
b=3
ls file{$a..$b}
我收到错误:
ls: cannot access 'file{1..3}': No such file or directory
我的理解问题是 bash 将 file{1..3}
解释为文件名,而不是模板。
我试图修复它但没有帮助。
任何帮助将不胜感激。
对于行
ls file{$a..$b}
您可以改用:
eval ls file{$a..$b}
因为Brace Expansion happens before Variable Expansion (see order of expansions).
所以 bash 看到:
file{$a..$b}
并首先尝试进行大括号扩展。由于 $a
和 $b
(解释为带有字符的美元,这是 before 变量扩展)不是有效的大括号扩展标记,因为它们需要是单个字符或数字,因此大括号扩展不会发生任何事情。在它(和其他一些扩展)变量扩展发生并且 $a
和 $b
被扩展为 1
和 3
之后,因此得到的参数是 "file{1..3}"
.
对于简单的用例,在文件名中没有空格 and/or 特殊字符,我只是:
ls $(seq -f file%.0f "$a" "$b")
或
seq -f file%.0f "$a" "$b" | xargs ls
或
seq "$a" "$b" | xargs -I{} ls file{}
或
seq "$a" "$b" | sed 's/^/file/' | xargs ls
或
seq "$a" "$b" | xargs printf "file%s\n" | xargs ls
对于更通用类型的解决方案,放弃 ls
可能会使用 find
。例如与 regex
组合,虽然这可能很棘手(参见 How to use regex with find command?):
#!/bin/bash
a=1
b=3
find . -regex "./file[$a-$b]"
我可以使用模板在我的目录中创建一些文件:
touch file{1..3}
要获取文件列表,我使用命令:
ls file{1..3}
输出:
file1 file2 file3
但是当我尝试在 bash 脚本中对变量使用相同的命令时:
#/bin/bash
a=1
b=3
ls file{$a..$b}
我收到错误:
ls: cannot access 'file{1..3}': No such file or directory
我的理解问题是 bash 将 file{1..3}
解释为文件名,而不是模板。
我试图修复它但没有帮助。
任何帮助将不胜感激。
对于行
ls file{$a..$b}
您可以改用:
eval ls file{$a..$b}
因为Brace Expansion happens before Variable Expansion (see order of expansions).
所以 bash 看到:
file{$a..$b}
并首先尝试进行大括号扩展。由于 $a
和 $b
(解释为带有字符的美元,这是 before 变量扩展)不是有效的大括号扩展标记,因为它们需要是单个字符或数字,因此大括号扩展不会发生任何事情。在它(和其他一些扩展)变量扩展发生并且 $a
和 $b
被扩展为 1
和 3
之后,因此得到的参数是 "file{1..3}"
.
对于简单的用例,在文件名中没有空格 and/or 特殊字符,我只是:
ls $(seq -f file%.0f "$a" "$b")
或
seq -f file%.0f "$a" "$b" | xargs ls
或
seq "$a" "$b" | xargs -I{} ls file{}
或
seq "$a" "$b" | sed 's/^/file/' | xargs ls
或
seq "$a" "$b" | xargs printf "file%s\n" | xargs ls
对于更通用类型的解决方案,放弃 ls
可能会使用 find
。例如与 regex
组合,虽然这可能很棘手(参见 How to use regex with find command?):
#!/bin/bash
a=1
b=3
find . -regex "./file[$a-$b]"