2016-10-06 37 views
1

我只是在bash中專門學習shell腳本,我希望能夠使用gzip從目標目錄獲取文件並將它們發送到不同的目錄。我在命令行中輸入目錄。 ext是用於我想壓縮的擴展名,文件將是新的壓縮文件。 我的腳本正確地將文件拉到,往返於所需的目錄,,但我得到一個沒有這樣的文件或目錄錯誤。我如何避免這種情況?Gzip沒有這樣的文件或目錄錯誤,仍然拉鍊文件

當前代碼

cd $1 

for ext in $*; do 
    for file in `ls *.$ext`; do 
     gzip -c $file > $2/$file.gz 
    done 
done 

和我的I/O

[email protected]:~/Desktop/60256$ bash myCompress /home/blackton/Desktop/ /home/blackton/ txt 
ls: cannot access *./home/blackton/Desktop/: No such file or directory 
ls: cannot access *./home/blackton/: No such file or directory 
gzip: alg: No such file or directory 
gzip: proj.txt: No such file or directory 
+0

用'find -name *「*。$分機」型F',而不是'LS * $ ext' – GMichael

回答

2

有兩個在這裏造成的問題不同的東西。 在您的外環

for ext in $*; do 
done 

你遍歷所有的命令行參數,使用每個作爲擴展名來搜索 - 包括目錄名。

自拓是第三個參數,您只需要在$3運行一次內部循環:

for file in `ls *.$3`; do 
    gzip -c $file > $2/$file.gz 
done 

下一個問題是空間。

你不想在這裏運行ls - 通配符擴展將直接提供文件名,例如, for file in *.$3,它會一次填充整個文件名的$filels的輸出在每個空間分割,因此最終會生成兩個文件名algproj.txt,而不是一個alg proj.txt

雖然這還不夠。無論何時使用它,您還需要引用$file,因此命令擴展爲gzip -c "alg proj.txt"而不是gzip -c alg proj.txt,該命令告訴gzip壓縮兩個文件。在一般情況下,你希望是一個文件名的所有變量的擴張應該被引用:

cd "$1" 

for file in *."$3"; do 
    gzip -c "$file" > "$2/$file.gz" 
done 

一個進一步的問題是,如果沒有匹配的擴展名的文件,通配符不會擴大,並執行該命令會

gzip -c "*.txt" > "dir/*.txt.gz" 

這將在目標目錄中創建一個字面上稱爲「* .txt.gz」的文件。避免這種情況的一個簡單方法是檢查原始文件是否首先存在 - 這也可以避免意外嘗試gzip奇怪命名的目錄。

cd "$1" 

for file in *."$3"; do 
    if [ -f "$file" ]; then 
     gzip -c "$file" > "$2/$file.gz" 
    fi 
done 
+0

我原本有兩個for循環,以獲得多個擴展名,但現在我意識到我是看着整個命令行。如果我想輸入多個文件擴展名,有沒有辦法從命令行查看某些參數?或者,即使我保留了外部循環但實現了if語句以避免查看壓縮其他文件? –

+0

這聽起來像是一個使用'shift'的好地方。它扔掉$ 1並將所有其他參數向下移動一個。你可以把它叫做兩次掃清了輸入和輸出目錄,然後使用$ *像你一樣本來,或者做一些「而$ 3是不是空的,過程擴展,移動」循環。 – Harun

0

你可以試試這個;

#!/bin/bash 
Src=$1 
Des=$2 
ext="txt" 
for file in $Src/*; do 
    if [ "${file##*.}" = "${ext}" ]; then 
     base=$(basename $file) 
     mkdir -p $2 #-p ensures creation if directory does not exist 
     gzip -c $file > $Des/$base.gz 
    fi 
done 
相關問題