• 締切済み

特定の名前のディレクトリーを検索して、それぞれの中身を圧縮して、それぞれ別名で保存したいのですが・

HELLO という名前のディレクトリー(複数)を検索し、 その中身を、それぞれ tar.gz して、別ディレクトリーに保存する、 という一連の流れを sh で実現したいと思っています。 HELLOという名前のディレクトリーは、必ず以下のような形で /root/data/site# の下にあります。 /root/data/site4/bbb/ccc/HELLO /root/data/site9/eee/HELLO /root/data/site20/HELLO それぞれの中身が以下のようになっていた場合、 /root/data/site4/bbb/ccc/HELLO/1.txt /root/data/site4/bbb/ccc/HELLO/2.txt /root/data/site4/bbb/ccc/HELLO/3.txt /root/data/site9/eee/HELLO/4.txt /root/data/site9/eee/HELLO/5.txt /root/data/site9/eee/HELLO/6.txt /root/data/site20/HELLO/7.txt /root/data/site20/HELLO/8.txt それぞれの中身を /home/backup というディレクトリー内に、site# を冠した名前で、 site4.tar.gz site9.tar.gz site20.tar.gz のように保存したいです。 *たとえばsite4.tar.gz は、解凍すると、1.txt 2.txt 3.txt という 3つのファイルが出来るようなtarballです。 find /root/data -name "HELLO" でHELLOディレクトリーを検索するとして、それが複数見つかったうえ、それぞれの中身を、 パスに含まれるsite#を冠したtarballにするあたりの処理が どうしてもうまく記述できません。 site#を冠したtarballにするのが無理なら、単純に、 1.tar.gz  2.tar.gz  3.tar.gz というような 名前でも構いません。 サンプルshをぜひご教授宜しく御願いいたします。

みんなの回答

  • t-okura
  • ベストアンサー率75% (253/335)
回答No.2

一重引用符の中では shell 変数が展開されません。awk に shell 変数を 渡すのは -v で awk の変数にして渡すのが定石のようです。そうすると find /root/data -type d -a -name 'HELLO' | awk -v DAY="$DAY" -F/ '{print "cd " $0 "; tar zcf /home/backup/" DAY "/" $4 ".tar.gz ."}' | sh になります。 ちなみに、上記は、 find で HELLO という名前を持つディレクトリを抽出し、そのデータを awk で処理しています。awk ではディレクトリ名を / で分割(-F/)する と、$0 はディレクトリ名全体を表し、$1 は最初の / の左側で空、$2 が root になります。以下同様です。 この分割したディレクトリ名の要素を print 文で shell で実行する コマンドに組み立て、 shell に入力して実行します。 パイプでつないでいるコマンドをひとつづつ実行するとわかるのではないでしょうか。

参考URL:
http://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/awk/intro/
tanpopo012
質問者

お礼

完璧に動作しました。頂いたURLで勉強します。ありがとうございました。

  • t-okura
  • ベストアンサー率75% (253/335)
回答No.1

find で処理対象を見つけ、awk でコマンドを組み立て、最後に sh で 実行するというのが、好みです。 下記でどうでしょうか。 find /root/data -type d -a -name 'HELLO' | awk -F/ '{print "cd " $0 "; tar zcf /home/backup/" $4 ".tar.gz ."}' | sh 最後の | sh の前までを実行すると、どのようなコマンドを実行するの か事前にチェックできます。

tanpopo012
質問者

お礼

すみません、もうひとつ、tarballの保存先を /home/backup としていましたが、 /home/backup/11-09-2008 のように、今日の日付を挿入したディレクトリーにしたいと思います。 #!/bin/sh DAY=`date +%m-%d-%Y` find /root/data -type d -a -name 'HELLO' | awk -F/ '{print "cd " $0 "; tar zcf /home/backup/$DAY" $4 ".tar.gz ."}' | sh とやっても、 $DAY は日付が代入されず$DAYのままで、 バックアップデータは /home/backup に出来てしまいました。 引き続きご教授宜しく御願い致します。

tanpopo012
質問者

補足

完璧に動作しました。芸術的。。 しかし何故この記述がこういう動作をするのかチンプンカンプンです。。できましたらコマンドごとに区切って、解説願えないでしょうか。。。

関連するQ&A

  • perlを使ったファイルの入出力について

    perl 初心者です。 perl を使ってデータ整理を試みていますが、方法がわからなくて困っています。 やりたい操作は、 1、ディレクトリ内にある特定の拡張子をもつすべてのデータファイルを読み込む 2、データソート 3、データファイル名を変更せずに、ソートしたデータを出力する 例 ディレクトリに以下のデータファイルがあるとします aaa.data bbb.data ccc.data : zzz.data これらのデータファイルをすべて読み込み、中身を整理した後に aaa.txt bbb.txt ccc.txt : zzz.txt となるように、それぞれのデータの名前を変更せずに出力したいと思っています。 スクリプトのサンプルなんかがあればありがたいです。

    • ベストアンサー
    • Perl
  • tar zcf  で Argument list too long のエラーが出る

    aaa下の中身を圧縮して test.tar.gz を作り、これを bbb下に移動させるのを 以下のようにshで行っています。 #!/bin/bash cd /aaa tar zcf test.tar.gz * mv test.tar.gz /bbb これを、なにか圧縮コマンドのオプションを使って 圧縮元と圧縮ファイル作成先を指定して、1行で済ますことは出来ますか? tar zcf /bbb/test.tar.gz /aaa/*   を試してみましたが、 -bash: /bin/tar: Argument list too long と出てしまいます。ご教授宜しく御願いいたします。

  • CSVに外部テキストファイルを列として追加する方法

    こんにちは。 CSVファイル(base.csv)の先頭列に、別のテキストファイル(add.txt)の中身を新規の列として挿入したいと考えているのですが、よい方法がわかりません。。。 どうのような方法を使えば対応することができるでしょうか? どうぞよろしくお願いいたします。 ■CSVファイル(master.csv) title,developer_name,seller_name,primary_genre_name,application_url AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE ■テキストファイル(add.txt) id 000 111 222 333 ↓ ■目標としたファイル(master.csv) id,title,developer_name,seller_name,primary_genre_name,application_url 000,AAA,BBB,CCC,DDD,EEE 111,AAA,BBB,CCC,DDD,EEE 222,AAA,BBB,CCC,DDD,EEE 333,AAA,BBB,CCC,DDD,EEE

  • xcopyで特定のファイルのみをコピーする方法

    xcopyもしくはcopyコマンドを使用し、ディレクトリ内の特定のファイル(複数)を コピーするにはどのようにしたら良いのでしょうか? 特定のファイルの数が多すぎるため、一行ずつコマンドを書くのは手間が掛るため、 何か良い方法があれば教えて頂きたいと思います。 excludeオプションを使用すれば特定のファイルを除外できるようですが、 反対の意味の特定のファイルのみをコピーしたいです。 例) c:\test内は以下のファイルがあります。 ・aaa.txt ・bbb.txt ・ccc.txt ・ddd.txt ・eee.txt これらのファイルの内、bbb.txtとddd.txtとeee.txtをコピーしたいです。

  • ファイルから検索条件を読み込んでGREPを実行したい

    INPUTファイルを以下のように作成します。 >input.txt aaa bbb ccc ・ ・ ・ 特定のディレクトリの複数ファイルに対して grepを順にaaa,bbb,ccc・・・ というようにinput.txtから読み込んで実行し、結果をそれぞれaaa.txt,bbb.txt,ccc.txt・・・ へ出力したいのですが、方法がわからなくて困っています。 どなたかご教授お願いいたします。

    • ベストアンサー
    • Perl
  • 名前をつけて保存する

    コマンドライン上に出力された結果を、コマンドライン上でファイル名を指定し、テキストファイルとして保存することは出来ますでしょうか? 作成するファイルは、作業中のフォルダに新規作成する、としたいのですが… たとえば、 カレントディレクトリがC\:/aaaであるとして、 bbb.cを実行したとき、 ----- 以下コマンドライン上の出力 ----- C:\aaa>aaa 1~nまでの素数を表示します nを入力 : 50 1~50までの素数は 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 です。 保存するファイル名を入力 : ccc.txt (ccc.txtと入力してenterを押すと保存) C:\aaa -------------- ここまで -------------- 上記の結果の、『1~nまでの…』から『です。』までを、ccc.txtとしてディレクトリC\:/aaaに新規作成したいのですが… どなたか出来る方がいらっしゃいましたら、ぜひご教授お願い致します。 もし、C言語でこのようなコトをするのは不可能であるのならば、『無理ですよ』という旨を伝えて頂ければ結構でございます。

  • tar圧縮ファイルが作成できず困っています。

    tarとgzipをパイプでつなげて使用すると、tar圧縮ファイルが正常に 作成できず困っています。(Solaris) *やりたいこと* ファイル一覧test.txtに記載されているファイルを一度に tar圧縮したい。(tar・gzip別々でなく) *コマンドライン* # tar cvfp - -I test.txt | gzip -c > test.tar.gz a aaa.txt 1K a bbb.txt 1K a ccc.txt 1K # ls -l test.tar.gz(←とりあえずファイルは作られている) -rw-r--r-- 1 root other 33235 5月 12日 10:03 test.tar.gz # gunzip test.tar.gz(←unzipもできる) gunzip: /usr/bin/gzip has 2 other links -- unchanged # ls -l test.tar -rw-r--r-- 1 root other 64076 5月 12日 10:03 test.tar # file test.tar(←この時点でおかしい。file種別がアーカイブじゃない) test.tar: ELF 32-ビット MSB 実行可能 SPARC バージョン 1[動的にリンクされています][取り除かれています] # tar xvfp test.tar(←エラーになる) tar: ディレクトリの検査合計エラーです。 # /bin/tar xvfp test.tar(←違うtarでやってみるとエラーがでる) tar: This does not look like a tar archive tar: Skipping to next header tar: Archive contains obsolescent base-64 headers tar: Read 2636 bytes from test.tar tar: Error exit delayed from previous errors 上記のような現象になって困っています。パイプ以降をcompressに するとふつうにいけるので、gzipがおかしいような気もするのですが。 サイトを検索するとみなさんGNUのgtarをお勧めしているようですが そちらもだめでした。 どなたか解決策をご存知の方がいたらご教授願います。

  • SQL文を教えてください。

    すみません、SQLを教えてください。 ID, 名前の2つのフィールドを持つテーブルがあります。 中身は以下のように入っています。 1, AAA 2. AAA 2, BBB 3, CCC 3, AAA 4, DDD 5, EEE, 5, DDD これを、名前のダブリをスキップしながら、 IDの大きな順番に名前を取り出したいのです。 結果は、以下のようになればいいです。 DDD EEE AAA CCC BBB どのようなSQLを組んだら実現できますか? よろしくお願いいたします。

  • 不特定ノードに出現する同じタグ要素の中身を置換して保存したい

    ある特定のタグ要素(例:hoge)がXML内のどこに現われるかわからないとき、それらの要素の中身を置換して、元のXMLと同じ構造を保ったまま保存したいと考えています。 XPathを使って//hogeと指定すればnodeListが抽出できますが、それらのrootNodeからの絶対パスを知る方法があればよいのですが。。。 当方DOMとXSLTを多少かじった程度で、SAXについては全くわかりませんが、どんな方法でもよいので実現できる方法があったらどなたかご教授くださいませ。 <?xml version="1.0" encoding="Shift_JIS"?> <root>  <hoge>変換前文字列1</hoge>  <aaa>   <hoge>変換前文字列2</hoge>  </aaa>  <bbb>   <ccc>    <hoge>変換前文字列3</hoge>   </ccc>   <hoge>変換前文字列4</hoge>   <hoge>変換前文字列5</hoge>  </bbb> </root> 上記のようなXMLを下記のように変更したい。 <?xml version="1.0" encoding="Shift_JIS"?> <root>  <hoge>変換後文字列1</hoge>  <aaa>   <hoge>変換後文字列2</hoge>  </aaa>  <bbb>   <ccc>    <hoge>変換後文字列3</hoge>   </ccc>   <hoge>変換後文字列4</hoge>   <hoge>変換後文字列5</hoge>  </bbb> </root>

    • ベストアンサー
    • XML
  • bshスクリプト で質問です。

    以下の内容のtmp.txtを aaa bbb ccc ddd eee fff 行末がbbbなら結合としたいです。 --希望結果-- aaa bbb ccc ddd eee fff この場合以下のスクリプトでうまくいかないのですが 原因を教えていただけますか? awk '{ gsub("bbb[\n]$","",$0); print }' tmp.txt OS、HP-UX11.0です。