Bash命令行重命名通配符 [英] Bash command-line to rename wildcard
问题描述
在我的 / opt / myapp
dir中,我有一个远程的自动化进程,它将删除< anything> ;版本> .zip
,其中< anything>
可以字面上是任何字母数字文件名,其中< version>
将是一个版本号。所以,这个自动化过程将会提供的例子有:
code>
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
$ 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屋!