- PR -

sed文の意味について

1
投稿者投稿内容
むー
常連さん
会議室デビュー日: 2002/11/29
投稿数: 42
投稿日時: 2003-05-29 12:28
「むー」でございます。
いつもお世話になっております。

唐突ですが、以下のsed文の処理の具体的な意味がわからず
四苦八苦しております。。。
お力添えいただけたら非常に幸いです。

----------------------------
sed '
:loop
s/#.*$//;s/[[:space:]]//g;/^$/d
/\\/ {
N;s/\\.*\n//;b loop
} ' ファイル
----------------------------

このスクリプトはBシェルで組まれています。
上記で指定した「ファイル」の内容として、
各行にログファイルのフルパスが指定されており、
コメントされている行もあります。
実行すると、コメントされている行は
出力結果から排除されます。

おそらくこれは3行目の処理の結果だと思うのですが、
他の行の処理について理解できませんでした。

なにとぞよろしくお願いします。
t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2003-05-29 16:10
何をするスクリプトかわかりませんが、
s/[[:space:]]//g
これは変じゃないですか?スペースが全部消えてしまうような。
本当は、その後ろの、/^$/dと合わせて、
/^[[:space:]]*$/d
のような気がします。

で、そうなった場合の意味は、

ラベル loop
#から行末までを削除、残りがスペース、タブ、改ページのみの行は削除
'\\'があるばあい、\から先を全て削除し、次の行を連結し、loopから先の処理を
もう一度行なう

です。


[ メッセージ編集済み 編集者: t-wata 編集日時 2003-05-29 16:11 ]
raccoon
ベテラン
会議室デビュー日: 2002/12/18
投稿数: 58
投稿日時: 2003-05-29 18:17
引用:

t-wataさんの書き込み (2003-05-29 16:10) より:
s/[[:space:]]//g
これは変じゃないですか?スペースが全部消えてしまうような。



ですよね。

まぁ確かに,このスクリプトがどのような目的・仕様で作られたものか
わかりませんので,元のままで要求を満たしているのであれば
外野がとやかく言うことでもないのかも知れませんが。
でもちょっと気になったので,「わたしならこんなかな」というのを。

わたしの考えでは,コメント('#'以降)を削除したあとに,
行末の不要な空白・タブを削除したかったのでは,と。
例えば

ABC [tab] DEF [tab][tab] # comment

のような場合,元のスクリプトだと

ABCDEF

と行中の空白・タブまで削除され,t_wataさんのやり方だと

ABC [tab] DEF [tab][tab]

と後ろのタブが残ってしまいます。
# 好きずきですが,わたしはこういうのスゴク気になるタチで・・・

そこで,こんなのはどうでしょう?
空白を削除してから空行を削除しているので,空白だけの行も消えます。

sed '
:loop
s/#.*$//;s/[[:space:]]*$//g;/^$/d
/\\$/ {
N;s/\\.*\n//;b loop
} ' ファイル

4行目も変更してます。"\"が行末にあった場合のみ継続行として扱うためです。
普通の感覚でいったら"\"はエスケープ文字なので,
"\"の直後が改行でなければ継続行とは解釈しないのが
わたしの感覚的にはあってます。
# ちなみにこれ,最後の行の行末が"\"だとうまくいかない
# かも知れませんね。試してませんが。


元のスクリプトの処理内容はt_wataさんのおっしゃるとおりですが,
「具体的な意味がわからない」とのことなので,ちょっとだけ具体的に。

:loop = ラベルの設定
s/#.*$// = 行の最後の'#'以降を削除
s/[[:space:]]//g = 空白・タブを削除
/^$/d = 空行を削除
/\\/ { ... } = "\"があったら{...}の処理をする
N;s/\\.*\n// = "\"以降の文字を削除し次の行を連結
b loop = :loopラベルにジャンプ

sedって確かに,慣れないと何やってるか難解ですよね。
でもmanで1つずつ調べれば,だいたいわかってくると思います。
# わたしもsedやawkはman見ないと「なんだっけ?」になる・・・(^^


[ メッセージ編集済み 編集者: raccoon 編集日時 2003-05-29 22:25 ]
t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2003-05-30 11:27
raccoonさんフォロー有難うございます。

他のスレッドを見て気づいたのですが、むーさんはsolaris使ってるんでしたっけ?
で、多分そのスクリプトは、Solarisで動作させてるのでしょう。
Solarisでは、/usr/bin/sedでは、[[:space:]]というのを期待通り?理解してくれません。
/usr/xpg4/bin/sedの方を使うと何が起こるか分かります。
むー
常連さん
会議室デビュー日: 2002/11/29
投稿数: 42
投稿日時: 2003-05-30 11:55
t-wataさん、raccoonさん、
ご回答、本当にありがとうございます。
非常ーによくわかりました。感謝感謝です!!

ここで私の頭の悪さゆえに再度確認させていただくことに
なってしまい申し訳ございません!
「b loop」から「loopラベル」にジャンプした後なのですが、
また同じ処理を繰り返すという意味なのでしょうか?
それともsed文を抜けて先の処理に移るのでしょうか?
(こんな質問をする自分の無知さが恥ずかしいです。。。)


最後にt-wakaさん、
他のスレッドまで気にかけていただいた上で
欲しかった回答をくださいましてありがとうございました!
嬉しかったです。
Solaris上で期待通り動作しなかった謎はすべて解けました(笑)。
むー
常連さん
会議室デビュー日: 2002/11/29
投稿数: 42
投稿日時: 2003-05-30 12:01
t-wataさん、raccoonさん、
ご回答、本当にありがとうございます。
非常ーによくわかりました。感謝感謝です!!

ここで私の頭の悪さゆえに再度確認させていただくことに
なってしまい申し訳ございません!
「b loop」から「loopラベル」にジャンプした後なのですが、
また同じ処理を繰り返すという意味なのでしょうか?
それともsed文を抜けて先の処理に移るのでしょうか?
(こんな質問をする自分の無知さが恥ずかしいです。。。)


最後にt-wakaさん、
他のスレッドまで気にかけていただいた上で
欲しかった回答をくださいましてありがとうございました!
嬉しかったです。
Solaris上で期待通り動作しなかった謎はすべて解けました(笑)。
t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2003-05-30 15:39
引用:

「b loop」から「loopラベル」にジャンプした後なのですが、
また同じ処理を繰り返すという意味なのでしょうか?
それともsed文を抜けて先の処理に移るのでしょうか?



aaa # comment1
bbb \
ccc # comment2
ddd # comment3


ってファイルを、処理したときに、";b loop"があるのとないのとで出力結果がどう変わるかを比べてみてください。

[ メッセージ編集済み 編集者: t-wata 編集日時 2003-05-30 15:40 ]
raccoon
ベテラン
会議室デビュー日: 2002/12/18
投稿数: 58
投稿日時: 2003-05-30 15:58
またもやt_wataさんの便乗になってしまいますが・・・(^^;;
もう1つ

AAA \
BBB \
CCC

も試してみるといいですよ。
このジャンプはループというより再帰呼び出し的ですね。
1

スキルアップ/キャリアアップ(JOB@IT)