![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
空白を含むディレクトリ名のあるループ処理
ディレクトリごとに圧縮してバックアップする処理を作っているのですが、
空白を含むディレクトリがあるとうまくいかないので困っています。
以下のようなスクリプトを作ってみました。
#!/bin/bash
for dirname in `ls -1 /data`
do
zip -r $dirname.zip /data/$dirname/
done
ディレクトリ構造は以下のとおりです。
/data
/data/data1
/data/data2
/data/data3
この状態だと問題ありませんが、
これに次のようなディレクトリがあると、
/data/data1 copy
ディレクトリ「data1 copy」としてうまく処理してくれず、
次のようなエラーになります。
zip warning: name not matched: /data/copy/
ディレクトリ「/data/copy/」がないと言う事だと思うのですが、
その前に「data1」の処理が2回行われたメッセージが出ていました。
zip コマンドを echo $dirname に変更して実行すると、
data1
data1
copy
data2
data3
と表示されたので、
「data1 copy」が「data1」と「copy」に分断されて処理されているようです。
「data1 copy」を「data1 copy.zip」として圧縮するにはどのようにしたらいいでしょうか。
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
#2です。
訂正と補足。find /data -mindepth 1 -maxdepth 1 -type d | xargs -i zip -r "`basename {}`".zip {}
と、basenameのところを" "で囲まないといけませんでした。
#1のお礼中で、xargsを使っていたのでそれに習いましたが、xargs -i を使わず、これでもいいです。
find /data -mindepth 1 -maxdepth 1 -type d -exec zip -r "`basename {}`".zip {} \;
また、#3の方が書いているように、空白文字(空白、タブ、改行)を含んだファイル名をfind+xargsで扱うときには、一般的には、ファイル名をヌル文字区切りにする
>find ... -print0 |xargs -0 ...
を使います。今回は、xargs で -i オプションを使っているので、たまたま必要ないだけです。
なお、IFSを空に設定しなくても、
>連続する複数ある区切り文字が1文字として処理されてしまいます
ということはないのですが、ファイル名が空白文字で始まったり終わったりしていると、IFSを空にしないでread dirnameだと、それら空白文字が落ちてしまいます。
ls を使う必然性がないなら、#4の方の回答のように、単にforにワイルドカードを書くだけの方が簡単です。
No.4
- 回答日時:
アスタを使えばスペースは展開されませんし、
さらにシェル変数をダブルクォートで括ることで展開を防げます。
#!/bin/bash
for dirname in /data/*
do
test -d "$dirname" || continue
zip -r "$dirname".zip /data/"$dirname"/
done
あと、while read ... を使う場合は IFS を設定した上で while read -r ...
としなければ連続する複数ある区切り文字が1文字として処理されてしまいます。
なので、手間と簡潔さを考えると上記のようにするのがよいと思います。
No.3
- 回答日時:
find を使うなら
find ... -print0 |xargs -0 ...
の方が安全でしょう.
ご回答いただきありがとうございます。
find の -print0 と xargs の -0 について調べてみました。
ヌル文字で区切る事によって、間違いが起きないようにするため、と解釈しました。
find の際には、付けるようにします。
No.2
- 回答日時:
元の形を生かすなら、
ls -1 /data | while read dirname
do
zip -r "$dirname".zip /data/"$dirname"/
done
>find でその階層しか検索しないようにする方法があれば教えてください。
findを使うなら、
find /data -mindepth 1 -maxdepth 1 -type d | xargs -i zip -r `basename {}`.zip {}
ご回答いただきありがとうございます。
他にいただいた回答なども含めて、まだいろいろと試している最中です。
元の形でもなんとかできそうなのですね。
元の形は、よくわからないで私が作ったので、なんとも言えない形でした。
と言うのは、それぞれのサブディレクトリ名で圧縮されるのはよかったのですが、
できれば別のディレクトリに圧縮ファイルを作成したかったのです。
質問では書かなかったのですが、圧縮後に別のディレクトリに移動させるために、
mv で処理していました。
これが find と xargs なら、たぶん basename で /data のルートからのディレクトリ名を省き、
サブディレクトリ名だけにできて、別のディレクトリ名と合わせる事で、
直接そこへ圧縮ファイルを作成できるのではないかと思っています。
いろいろなやり方があるので、他にいただいた回答も試して、どうするか決めたいと思います。
No.1
- 回答日時:
古式ゆかしい方法だと
find + xargs
ご回答いただきありがとうございます。
find と xargs で次のようにするとうまくいけたような気がします。
find /data/* -type d | xargs -i zip -r {}.zip {}
find と xargs の使い方を調べて、なんとかこうしたのですが、
これで問題ないでしょうか。
今は、/data/data1 以下の階層にはディレクトリがないのでいいのですが、
例えば、階層が「/data/data1/sub1」などとあった場合には、
find でそのディレクトリが検索されてしまい、
/data/data1/sub1 の処理がされる上に、
/data/data1 の処理の中にも sub1 がされてしまいます。
find でその階層しか検索しないようにする方法があれば教えてください。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ftpのmgetコマンドの自分の格納...
-
拡張子.dどういう意味
-
linuxのコマンドラインで、拡張...
-
ホームページのディレクトリを...
-
「ドット(.)」と「¥」の意味...
-
「照合パターンに合いません」...
-
7zを使うとフォルダの中身がす...
-
Linuxコマンドについて
-
バッチファルの置き場所
-
#./configureの時点でダメです。
-
2TBのUSBメモリを2000円ほどで...
-
scpによるデータ転送後、ディレ...
-
シンボリックリンクについて
-
make時に出てきたエラーメッセ...
-
Linuxのinodeについて。
-
"cp -a"と"cp -r"の違い
-
ディレクトリのみにヒットする...
-
~/.profile を変更するにもみつ...
-
Minecraftにforgeを入れたら、...
-
grepで、再帰的に検索する場合...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
拡張子.dどういう意味
-
7zを使うとフォルダの中身がす...
-
ftpのmgetコマンドの自分の格納...
-
ホームページのディレクトリを...
-
ファイル名で / (スラッシュ...
-
FTPコマンドのCDについて
-
make時に出てきたエラーメッセ...
-
「照合パターンに合いません」...
-
/(スラッシュ)で区切ったフル...
-
linuxコマンド mkdirでディレ...
-
tarコマンドのエラーについて
-
"cp -a"と"cp -r"の違い
-
Linuxコマンドについて
-
「ドット(.)」と「¥」の意味...
-
scpによるデータ転送後、ディレ...
-
バッチファルの置き場所
-
FTPでPUTできない原因は何?
-
#./configureの時点でダメです。
-
エクセルでハイパーリンクを連...
-
SAMBA上に書き込んだファイルの...
おすすめ情報