プロが教える店舗&オフィスのセキュリティ対策術

当方、UNIX系OSを使っているCUI初心者です。

awkかsedを使って、テキスト内の文字列を取得したいのですが、
上手くいきませんorz

例えば、テキスト内にデータ名があったとします。
そのデータ名の拡張子を取得する場合は、どうすればいいのでしょうか?

皆さん、教えてくださいm(_)m

A 回答 (4件)

ちなみに「xargs を使ってファイルを 1つずつ処理」というのはちょっとさみしい. それは while とか read を使った方がいいんじゃないかなぁ. 例えば


cat files.lst | while read file; do zip $file.zip $file; done
とか
cat files.lst | while read file; do zip ${file%.*}.zip $file; done
みたいに.
    • good
    • 0

>テキストから抜き出したデータ名を変数に格納して、


>zipコマンドでデータの圧縮を行いたいのですが、

これはTacosanさんが書かれているようにxargsを使うと簡単です。
仮にfiles.lstに
text1.txt
text2.txt
text3.txt
と書いてあって、それを各text*.txt.zipに圧縮するとしたら
$ cat files.lst | xargs -i zip {}.zip {}
という感じです。

xargsは標準入力からの文字列を受け取ります。-iオプションをつけると各行ごとにxargsの後ろに書いたコマンドを実行します。そのとき標準入力から読んだ文字列を{}の代わりに置き換えて実行します。
なので、たとえばcatで標準出力に書き出したうちの一行目"text1.txt"がxargsの入力にはいると
zip text1.txt.zip text1.txt
というコマンドを実行します。同様にtext2.txt, text3.txtもそれぞれ対応したzipコマンドが実行されます。
xargsのオプションに-tも追加すると、実行しているコマンドが表示されるようになるので不慣れなうちは-tもつけて何を実行しているか確認しながら作業するとよいです。


別の方法としてはシェルスクリプトにしてしまうのも簡単なやり方です。
sedやawkを使うということはLinuxか*BSDなどUNIX系のシステムでしょうか。とするとshやcshといったシェルを使っていると思います。
仮にsh(bash)を使うとすると
#!/bin/sh

# ファイルリストの読み込み
files=`cat files.lst`
# ファイル一つごとにzip処理
for afile in ${files}; do
 zip ${afile%.*}.zip ${afile}
done
という感じです。ファイルのリストをいったん変数filesに読み込んで、その各要素ごとにfor - do - doneを繰り返します。繰り返しごとに変数afileにはfilesの各要素が一つずつ順に入ります。
先のxargsだと面倒だったのでtext1.txtを圧縮したファイルはtext1.txt.zipと元のファイル名に.zipを単につなげてみましたが、上のシェルスクリプトではちょっと気を利かせてtext1.txtを圧縮したものはtext1.zipになるようにしています。ミソは${afile%.*}というのが変数afileに入っているファイル名から拡張子を抜いた文字列なのですけれど、詳しくはbashのマニュアル(man bashで読める)をみてください。

cshでも表記は変わりますが同じように処理することができます。

>処理したいデータ→テキストにデータ名を保存→変数にデータ名を格納
>→変数を使ってデータをzipコマンドで圧縮
という構図だとシェルスクリプトでやるとぴったりかもしれませんね。
シェルスクリプトの中から必要に応じてsedやawkを呼び出してもよいです。
いっそ、awkやperlで全部書いてしまうと見通しがよいかもしれません。
    • good
    • 0
この回答へのお礼

ありがとうございました!

仰るとおり、xargs コマンドでいけました♪

cat "test.txt" | xargs zip

これでtest.txt内に記載されているデータ名の実データが、
まとめてzipで圧縮して一つにすることができました^^v

皆さんのおかげで助かりました!

また、何か壁にぶち当たった時は、質問させていただきます。
その時は、よろしくお願いしますm(_)m

お礼日時:2008/06/17 20:16

「データ名」というのがよくわからんのだけど, 「データファイルの名前」だったら xargs を使えるとおいしいかもしれない.


使い方は man を参考にしてください.
    • good
    • 0

「データ名」の入り方次第でちょっと変わります。


例えば1行に一つのデータ名「だけ」が書かれているのなら
sed -e 's/^.*\.\(.*\)$/\1/'
とか言う感じ。(データ名に拡張子がない("."を含まない)ときにその行をとばしたいなら、上記sedコマンドの後ろに-et -edを追加します。)

(最初の.*で前方の要らない部分をとばして、次の\.が拡張子の前の"."にマッチ。次の文字から行末($)までの全ての文字を\(.*\)で受けて、それを\1で取り出します。)

カンマ区切りでいくつかのデータがあって、その中の一つのフィールドが「データ名」ならば
sed -e 's/^.*\.\([^,]*\).*$/\1/'
とかでしょうか。
もうちょいかっこよく書けたりもしそうですが。

(行頭(^)から不要部分(拡張子を示す"."の前まで)を.*\.で読み飛ばし、その後ろから区切りである","を含まない文字列を拡張子として受けます。","を見つけたらそこより後ろは.*$で読み飛ばします。で、その拡張し部分を\1として取り出します。)


awkでも似たような感じ。1行にいくつかのフィールドがあって、その中の特定のフィールドでだけ拡張子をチェックしたいとか、1行中の複数のフィールドに「データ名」があるとかの場合はフィールドの切り出しをやってくれるawkの方が処理しやすいですね。
    • good
    • 0
この回答へのお礼

ありがとうございます!

なるほど・・・正規表現を使ってやればいいわけですね。

ちなみに、1行につき一つのデータ名が入っている状態です。
試行錯誤しながら、やっていきたいと思います♪

もう一つ質問なのですが・・・
テキストから抜き出したデータ名を変数に格納して、
zipコマンドでデータの圧縮を行いたいのですが、
これもやり方がサッパリでorz

処理したいデータ→テキストにデータ名を保存→変数にデータ名を格納
→変数を使ってデータをzipコマンドで圧縮
という構図を描いています。

厚かましいとは思いつつも、困り果てているので、
どなたか教えてくださいm(_)m

お礼日時:2008/06/16 21:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!