使用mv命令将无法将*识别为通配符

时间:2014-02-27 16:50:57

标签: bash shell awk mv

我有这个脚本,我知道它中的awk命令有效,但是当我想使用与mv命令*命令执行任务的文件相同的名称来保存输出时{{ 1}}不是用作通配符而是用作字符,我最终得到一个名称如下的文件:

  

Algeria_BER _ * _ sites.txt

剧本:

#!/bin/bash

for i in Algeria_BER 
do

 echo awk 'FNR==NR{a[++i]=$0;next} {print a[FNR] RS $0}' \
     reduced_filt_MAF_b37_chr1_${i}_ldhat.txt_names ${i}_*_sites.txt > $$.tmp &&
   mv $$.tmp "${i}_*_sites.txt"

done

2 个答案:

答案 0 :(得分:4)

问题在引用。 Glob模式应该在引用之外,因此您需要:

"${i}_"*"_sites.txt"

答案 1 :(得分:4)

mv命令无法识别*通配符; shell确实。

此:

foo*.txt

展开到当前目录中名称以foo开头并以.txt结尾的所有文件的列表。如果您将foo*.txt作为参数传递给mv,则mv命令永远不会看到*;它只能看到文件列表。

这意味着如果您有文件foo1.txtfoo2.txt,请执行以下操作:

mv foo*.txt bar*.txt

foo1.txt重命名为bar1.txt,将foo2.txt重命名为bar2.txt - 因为bar*.txt只能展开到列表已存在的文件 。如果没有匹配bar*.txt的现有文件,则上述内容扩展为:

mv foo1.txt foo2.txt bar42.txt

除非bar42.txt恰好是目录,否则这是一个错误。它将以各种其他方式扩展,具体取决于当前存在的文件 - 并且它们都不可能是您想要的。

如果没有匹配给定通配符的文件,则行为取决于shell和您当前的设置。在bash中,使用默认设置时,通配符不会展开 - 这可能是您获取名称中包含*的文件的原因。

有批量重命名工具可以做你想要的(我自己没有用过)。

我经常使用的另一种方法是将文件列出到文本文件,手动编辑文件,然后将其作为脚本运行。例如,我可能会这样做:

ls foo*.txt > tmp

然后手动编辑tmp以将每一行转换为执行我想要的命令:

foo1.txt
foo2.txt

- >

mv foo1.txt bar1.txt
mv foo2.txt bar2.txt

然后运行命令:

. ./tmp