2012-07-30 89 views
9

比方说,我在我的当前目录下面的文件:Bash命令只移动一些文件?

1.jpg 
1original.jpg 
2.jpg 
2original.jpg 
3.jpg 
4.jpg 

是否有终端/庆典/ Linux命令,可以做到像

if the file [an integer]original.jpg exists, 
    then move [an integer].jpg and [an integer]original.jpg to another directory. 

执行这样的命令的东西会造成1。 jpg,1original.jpg,2.jpg和2original.jpg在自己的目录中。

备注 这不一定是一个命令。我可以是简单命令的组合。也许像将原始文件复制到新目录。然后对newdir中的文件执行一些正则表达式过滤器,以获取旧目录中仍需复制的文件名列表等。

+3

这就是为什么超级用户学习编程:)好问题。 – 2012-07-30 19:09:57

+0

您是否担心可能存在“5original.jpg”而不是“5.jpg”的情况? – 2012-07-30 21:35:13

回答

6

打开扩展的glob支持将允许您编写一个类似于正则表达式的模式,它可以处理具有多位整数的文件,如'87 .jpg'和'87original.jpg'。然后可以用来从名称o中去除“原始”找到一个允许您将两个相关文件放在一起的文件。

shopt -s extglob 
for f in +([[:digit:]])original.jpg; do 
    mv $f ${f/original/} otherDirectory 
done 

在扩展图案,+(x)匹配的一个或多个的东西的括号内,类似于正则表达式x+。这里,x是任何数字。因此,我们匹配当前目录中名称由1或多个数字后跟“original.jpg”组成的所有文件。

${f/original/}bash的模式替换的示例。它将从f的值中删除第一次出现字符串“original”。所以如果f是字符串“1original.jpg”,那么${f/original/}是字符串“1.jpg”。

-1

您可以使用Regex语句在文件名中查找“匹配”你正在翻阅。然后在您找到的“匹配”上执行您的操作。

+1

谢谢,你可以根据上面给出的文件名显示一个示例解决方案吗?我从看到示例解决方案中学到了最好的东西 – John 2012-07-30 19:15:50

-1

integer=0; while [ $integer -le 9 ] ; do if [ -e ${integer}original.jpg ] ; then mv -vi ${integer}.jpg ${integer}original.jpg lol/ ; fi ; integer=$[ $integer + 1 ] ; done

请注意,这里的 “笑” 是目标目录。你可以把它改成你喜欢的任何东西。此外,您可以将9更改为while [ $integer -le 9 ]以检查大于9的整数。现在它从0开始并在检查9 *之后停止。

编辑:如果你愿意,你可以用回车代替我的代码中的分号,它可能会更容易阅读。而且,您可以用这种方式将整个块粘贴到终端中,即使这可能不会立即显而易见。

+3

您应该考虑以易于阅读和维护的方式来格式化您的代码。 – jordanm 2012-07-30 20:14:24

3

很好,不是直接的,但它是一个oneliner(编辑:没有了):

for i in [0-9].jpg; do 
    orig=${i%.*}original.jpg 
    [ -f $orig ] && mv $i $orig another_dir/ 
done 

编辑:也许我应该指出我的解决方案:

  • for i in [0-9].jpg:执行循环体每个jpg文件都有一个数字作为文件名。存储整个文件名中$i
  • orig={i%.*}original.jpg:在$orig保存文件名可能为“原始文件”
  • [ -f $orig ]:通过test(1)(在[ ... ]东西)如果$i原检查文件是否存在。如果是,请将这两个文件移动到another_dir。这是通过&&完成的:只有在测试成功时才会执行后面的部分。
+1

您应该将代码格式化为多行,以便于阅读。另外,你可以避免使用'$ {i ## * /}'来代替basename。 – jordanm 2012-07-30 20:15:58

+0

谢谢。避免使用basename和使用模式匹配是一个好主意,但'$ {i ## * /}'不适合我。我用'$ {i%。*}'代替。 – lewurm 2012-07-30 21:33:45

1

,下面这些工作,是很容易理解(与你的号码的实际范围替换out与输出目录,并{1..9}

for x in {1..9} 
do 
if [ -e ${x}original.jpg ] 
then 
mv $x.jpg out 
mv ${x}original.jpg out 
fi 
done 

可以很明显的也进入它作为一个单行。

+3

在没有解释的情况下下调完全有效的答案是没有意义的... – houbysoft 2012-07-30 20:18:04

2

这应该严格任何数字前缀的工作,即234.jpg

for f in *original.jpg; do 
    pre=${f%original.jpg} 
    if [[ -e "$pre.jpg" && "$pre" -eq "$pre" ]] 2>/dev/null; then 
    mv "$f" "$pre.jpg" targetDir 
    fi 
done 

"$pre" -eq "$pre"给出了一个错误,如果不是整数

编辑:
如果存在original.jpg.jpg都失败。
$pre然后是空字符串并且"$pre" -eq "$pre"为true。