你如何将ls的输出发送到mv?

38 bash command-line

我知道你可以用它做find,但是是有办法的输出发送lsmv在UNIX命令行?

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以获取详细的解释和建议.

  • 哪个*与更简单的"mv*.boo subdir"*完全相同*除了*你们不会处理名字中带空格的文件,如果你有"别名ls ='ls --color =它将不起作用总是'".你不应该以这种方式依赖ls的输出. (11认同)
  • 这仍然不能解决文件名中空格的问题。 (2认同)

Cur*_*son 7

到目前为止,对于包含空格的文件名,没有一个答案是安全的。尝试这个:

for i in *; do mv "$i" some_dir/; done
Run Code Online (Sandbox Code Playgroud)

您当然可以使用任何您喜欢的 glob 模式来代替*.


Cra*_*ght 5

不完全确定你在这里想要达到的目标,但这里有一种可能性:

"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如何在不阅读手册页或转到我的"可爱技巧"文件的情况下工作.

希望这可以帮助.

  • 没有特别需要`ls` - "for in in*; do any; done"也适用. (3认同)

syb*_*eon 5

查看find -exec {}它可能是一个更好的选择,ls但它取决于你想要实现的目标.

  • 你应该给出一个例子,比如"找到.-name'*.txt'-exec cp'{}'/ stuff';'".特别是因为引用正确并不明显. (5认同)