使用ls $ variable的bash脚本

时间:2011-05-02 15:26:04

标签: bash

我正在尝试让我的脚本以“$ variable”形式显示所有文件。*

参数始终是扩展名为.001的文件 我想找到所有具有相同名称但扩展名不同的文件,例如$ file.002,file.003等。例如:

first="$1"
others=${first%.001}
ls $others"*"

我的问题是该文件名为file[success].mpg.001 什么得到了ls,file[success].mpg*给了我 ls: cannot access file[success].mpg*: No such file or directory 因为ls需要看到:

file\[success\].mpg*

我一直在尝试一切,我注意到的一件事是 ls喂参数$ 1有效,但是如果在我完成file = $ 1之后输入$ file。 所以我想如何将变量更改为参数?

4 个答案:

答案 0 :(得分:7)

您可以使用bash的{​​{1}}命令重新格式化字符串。此外,您无需引用printf

*

#!/bin/bash first="$1" others=$(printf %q "${first%.001}") ls $others* 以可用作shell输入的格式重新格式化字符串(关于printf %q的手册页)。

编辑评论
上述解决方案不适用于文件名中的空格。对于那些情况(如已经提到的其他答案),最好不要使用bash,而是正确引用所有变量:

printf

答案 1 :(得分:5)

你应该引用变量,而不是通配符:

ls -- "$others"*

双短划线停止搜索选项,以便即使others以短划线开头,此代码仍然有用。

请注意,ls通常是脚本中的错误解决方案。仅在您确实要打印列表时使用它,例如长格式:

ls -l -- "$others"*

如果您只想打印名称,则根本不需要ls

echo "$others"*

很遗憾,您无法将--echo一起使用。 但是,如果您想要一个文件名数组,请使用

filenames=("$others"*)

如果您想迭代它们,请使用

for filename in "$others"*

答案 2 :(得分:3)

你离我太远了。我的第一个修复是将第3行更改为以下内容:

ls -- "${others}".*

这会扩展$others并允许全局发生。将*扩展到所有匹配文件名列表是shell的责任。然后将文件名列表发送到ls。听起来在大多数情况下,ls会看到类似的东西:

file1.001 file1.002 file1.003 ...

但是,当没有文件存在时,shell将glob传递给ls并且它将看到星号:

file1.*

因此,你的行ls $others"*"会附加一个字面星号,它将会看到。

除非您有文件名file1.*(带有文字星号),否则ls将失败。

另一种选择是使用basename:

first="$1"
others=`basename -- "$first" .001`
ls -- "${others}".*

使用basename为您提供了删除目录等优势。

但是,正如其他人所指出的那样,根据您对文件列表的处理方式,find可能会更好。

编辑:双连字符不适用于所有* nix变体,但告诉lsbasename命令没有其他cli参数。引用您的变量可能是一种最佳实践,但除了数据不可信外,我更喜欢简单地将它们关闭。了解您的数据和报价。

答案 3 :(得分:1)

使用find代替ls:

$ ls weg.*
ls: weg.*: No such file or directory
$ find . -name weg.\*
$