2015-05-26 198 views
1

以我/opt/myapp DIR我有一个远程的,自动化过程将被丢弃的形式<anything>-<version>.zip,其中<anything>可以从字面上是任何字母数字文件名的文件,并且其中<version>将是一个版本号。所以,这是什么自动化过程将发表的例子是:击命令行重命名通配符

  • fizz-0.1.0.zip
  • buzz-1.12.35.zip
  • foo-1.0.0.zip
  • bar-3.0.9.RC.zip

等。通过这个问题的范围控制,我是保证只有其中一个ZIP文件将存在/opt/myapp在任何给定的时间。我需要编写一个Bash shell命令,它将重命名这些文件并将它们移动到/opt/staging。对于重命名,ZIP文件需要删除其版本。所以/opt/myapp/<anything>-<version>.zip被重新命名并移动到/opt/staging/<anything>.zip。使用上面的例子:

  • /opt/myapp/fizz-0.1.0.zip =>/opt/staging/fizz.zip
  • /opt/myapp/buzz-1.12.35.zip =>/opt/staging/buzz.zip
  • /opt/myapp/foo-1.0.0.zip =>/opt/staging/foo.zip
  • /opt/myapp/bar-3.0.9.RC.zip =>/opt/staging/bar.zip

目录此举是明显和容易的,但重命名让我把我的头发拉出来。我需要以某种方式保存<anything>,然后在命令中重新访问它。 该命令必须是通用的,并且不能有任何参数。

我最好的尝试(它甚至没有接近工作)至今是:

文件= *拉链。文件= ?; mv文件/ opt/staging

有关如何做到这一点的任何想法?

+0

感谢@chepner但**请取消标记为重复数据删除!**在该问题的用户* *知道这个词的“doc”总是出现在文件名,在这里我不知道是什么''是! **这不是同一个问题,需要一个不同的解决方案!**标记适度。 – smeeb

+0

这是如何使它不同? (建议的副本不再链接,因此很难判断其解决方案是否会工作)。 –

回答

2
for file in *.zip; do 
    [[ -e $file ]] || continue # handle zero-match case without nullglob 
    mv -- "$file" /opt/staging/"${file%-*}.zip" 
done 

${file%-*}在文件名的最后一个-后删除所有内容。因此,我们将fizz-0.1.0.zip更改为fizz,然后添加前导/opt/staging/和尾随.zip


为了使这个更通用的(带有多个扩展名工作),请参阅下面的功能(可调用的命令,函数体也可以被放到一个脚本以#!/bin/bash家当,如果除去local声明) :

stage() { 
    local file ext 
    for file; do 
    [[ -e $file ]] || continue 
    [[ $file = *-*.* ]] || { 
     printf 'ERROR: Filename %q does not contain a dash and a dot\n' "$file" >&2 
     continue 
    } 
    ext=${file##*.} 
    mv -- "$file" /opt/staging/"${file%-*}.$ext" 
    done 
} 

...与函数定义,你可以运行:

stage *.zip *.txt 

...或者你选择的任何其他模式。

+0

@JonathanLeffler,...参加测试路线的部分原因是我收集到OP想要将其称为脚本(这也是为什么我放入关于从函数转换它的注释);不一定能够控制呼叫环境。 –

0
f=foo-1.3.4.txt 
echo ${f%%-*}.${f##*.} 
+0

它看起来像你在那里使用一些相当晦涩的shell语法,它保证解释它的功能。 – SamB

+0

@SamB,参数扩展并不是那么模糊 - 实际上,我的答案也使用它。请参阅http://wiki.bash-hackers.org/syntax/pe –