2015-05-26 155 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 –