lhu*_*ath 74
ls 是一个用于显示某些目录中文件名统计信息的工具.
它不是一个工具,您应该使用它来枚举它们并将它们传递给另一个工具以便在那里使用它.解析ls是几乎总是错的事情,并且它在许多方面窃听.
有关分析LS,你应该的捣蛋的详细文件真的去读一读,看看:http://mywiki.wooledge.org/ParsingLs
相反,您应该使用globs或find,具体取决于您要实现的目标:
mv * /foo
find . -exec mv {} /foo \;
Run Code Online (Sandbox Code Playgroud)
解析的不良主要原因ls是ls将所有文件名转储到单个输出字符串中,并且没有办法告诉文件名.如你所知,整个ls输出可以是一个文件名!
解析不良的第二个来源是ls世界上一半使用bash的破碎方式.for当他们做以下事情时,他们会神奇地思考他们希望它做什么:
for file in `ls` # Never do this!
for file in $(ls) # Exactly the same thing.
Run Code Online (Sandbox Code Playgroud)
for是一个bash内置迭代参数.并$(ls)获取输出ls并将其分成任何地方的参数spaces,newlines或者tabs.这基本上意味着,你是在迭代单词,而不是文件名.更糟糕的是,你要求bask取出每个残缺的文件名,然后将它们视为可能与当前目录中的文件名匹配的globs.因此,如果你有一个文件名,其中包含一个与当前目录中的其他文件名匹配的字符串,则该字将消失,所有匹配的文件名将会出现!
mv `ls` /foo # Exact same badness as the ''for'' thing.
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 21
一种方法是使用反引号:
mv `ls *.boo` subdir
Run Code Online (Sandbox Code Playgroud)
编辑:但是,这是脆弱的,不推荐 - 请参阅@ lhunath的asnwer以获取详细的解释和建议.
到目前为止,对于包含空格的文件名,没有一个答案是安全的。尝试这个:
for i in *; do mv "$i" some_dir/; done
Run Code Online (Sandbox Code Playgroud)
您当然可以使用任何您喜欢的 glob 模式来代替*.
不完全确定你在这里想要达到的目标,但这里有一种可能性:
"xargs"部分是其他所有设置的重要部分.这样做的结果是获取"ls"输出的所有内容并为其添加".txt"扩展名.
$ mkdir xxx # $ cd xxx $ touch a b c x y z $ ls a b c x y z $ ls | xargs -Ifile mv file file.txt $ ls a.txt b.txt c.txt x.txt y.txt z.txt $
这样的事情也可以通过以下方式实现:
$ touch a b c x y z
$ for i in `ls`;do mv $i ${i}.txt; done
$ ls
a.txt b.txt c.txt x.txt y.txt z.txt
$
我有点像第二种方式更好.我永远不会记得xargs如何在不阅读手册页或转到我的"可爱技巧"文件的情况下工作.
希望这可以帮助.
查看find -exec {}它可能是一个更好的选择,ls但它取决于你想要实现的目标.