Bash命令行重命名通配符 [英] Bash command-line to rename wildcard

查看:136
本文介绍了Bash命令行重命名通配符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 / opt / myapp dir中,我有一个远程的自动化进程,它将删除< anything> ;版本> .zip ,其中< anything> 可以字面上是任何字母数字文件名,其中< version> 将是一个版本号。所以,这个自动化过程将会提供的例子有:


  • fizz-0.1.0.zip code>

  • 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
    $ b

    目录的移动是显而易见的,但重命名却让我把头发拉出来。我需要以某种方式保存< anything> ,然后在命令中重新访问它。 该命令必须是通用的,并且可以不带任何参数。



    到目前为止,我的最佳尝试(甚至没有接近工作) :


    file = *。zip;文件= ?; mv file / opt / staging


    关于如何做到这一点的任何想法?解决方案

 用于* .zip文件。做
[[-e $ file]] ||继续#处理zero-match case没有nullglob
mv - $ file/opt/staging/\"${file%-*}.zip
完成

$ {file% - *} > - 在文件名中。因此,我们将 fizz-0.1.0.zip 更改为 fizz ,然后添加一个前导 / opt / staging / 和尾部 .zip






为了使这个更通用(使用多个扩展),请看下面的函数(可调用为一个命令;函数体也可以放在脚本中,使用#!/ bin / bash shebang,如果删除了 local 声明):

  stage(){
本地文件ext
用于文件;做
[[-e $ file]] ||继续
[[$ file = * - *。*]] || {
printf'错误:文件名%q不包含短划线和点'\\''$ file>& 2
continue
}
ext = $ {file ## *。}
mv - $ file/opt/staging/\"${file%-*}.$ext
done
}

...定义了该函数,您可以运行:

  stage * .zip * .txt 

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

In my /opt/myapp dir I have a remote, automated process that will be dropping files of the form <anything>-<version>.zip, where <anything> could literally be any alphanumeric filename, and where <version> will be a version number. So, examples of what this automated process will be delivering are:

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

etc. Through controls outside the scope of this question, I am guaranteed that only one of these ZIP files will exist under /opt/myapp at any given time. I need to write a Bash shell command that will rename these files and move them to /opt/staging. For the rename, the ZIP files need to have their version dropped. And so /opt/myapp/<anything>-<version>.zip is renamed and moved to /opt/staging/<anything>.zip. Using the examples above:

  • /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

The directory move is obvious and easy, but the rename is making me pull my hair out. I need to somehow save off the <anything> and then re-access it later on in the command. The command must be generic and can take no arguments.

My best attempt (which doesn't even come close to working) so far is:

file=*.zip; file=?; mv file /opt/staging

Any ideas on how to do this?

解决方案

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

${file%-*} removes everything after the last - in the filename. Thus, we change fizz-0.1.0.zip to fizz, and then add a leading /opt/staging/ and a trailing .zip.


To make this more generic (working with multiple extensions), see the following function (callable as a command; function body could also be put into a script with a #!/bin/bash shebang, if one removed the local declarations):

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
}

...with that function defined, you can run:

stage *.zip *.txt

...or any other pattern you so choose.

这篇关于Bash命令行重命名通配符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆