2016-10-06 7 views
1

私はちょうどbashでシェルスクリプトを学んでいる、私はgzipを使用してターゲットディレクトリからファイルを取って、別のディレクトリに送信することができるようにしたい。私はコマンドラインにディレクトリを入力します。 extは私が圧縮したい拡張子用で、ファイルは新しいzipファイルになります。 私のスクリプトは、ファイルを適切なディレクトリに入れて、希望するディレクトリに送りますが、そのようなファイルやディレクトリにはエラーがありません。これを避けるにはどうすればいいですか?Gzipそのようなファイルやディレクトリのエラーは、まだzipsファイル

現在のコード

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

*代わりにlsの 'の' *見つける-name「*。$のEXT」型F'を使用してください。$ 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となり、一度にファイル名全体が$fileとなります。 lsからの出力は各スペースで分割されているので、ではなく、algproj.txtという2つのファイル名になります。

それだけでは不十分です。また、使用するたびに$fileを引用する必要があるので、コマンドはgzip -c alg proj.txtの代わりにgzip -c "alg proj.txt"に展開され、gzipに2つのファイルを圧縮するよう指示します。一般的に、あなたはファイル名であることを期待し、すべての変数の展開が引用されるべきである。

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

私はもともと複数の拡張子を取得するために、ループのための2つを持っていたが、私は今、私がいた実現コマンドライン全体を見る。複数のファイル拡張子を入力したいのであれば、コマンドラインから特定のパラメータだけを見る方法はありますか?あるいは、私が外側のループを保持していても、if文を実装して他のファイルを圧縮しないようにすることはできますか? –

+0

これは 'shift'を使うのに良い場所のようです。それは$ 1を捨て、他のすべてのパラメータを1つ下に移動します。入力と出力のディレクトリをクリアして元のように$ *を使用するか、あるいは$ 3が空でないうちに何らかの処理を行うために2回呼び出すことができます。 – 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 
関連する問題