これが怖いの自分だけ?というものありますか?

あるテキストで、BB と書かれた行の1カラム目の数字を100に変えるとき
sed -ri "BB/s[^\t]+(.*)/100\1/" sample.txt
を使うように言われて実際、以下の置換がなわれるのですが、

BBの含まれる行で/タブ以外で始まる一連の文字を/100として一連の文字にする/
と解釈しましたが、[^\t]を
「タブ以外で始まる一連の文字」という解釈では、1カラム目以外にも、すべての文字列に
当てはまってしまうと思うのですが、なぜ、上記のsedでよいのでしょうか?


50 !<BB this is a pen

100 !<BB this is a pen

A 回答 (2件)

sed の s での動作は


○1行ずつ「マッチしてたら置換」をする
○(g等のフラグを付けない限り) 最初にマッチした部分だけ処理される。
○同じ行に対して、1回目マッチと2回目のマッチとでは重複しない

また、正規表現で使われている + * は「複数候補がある場合、一番長いものを採用する」というもの。

ということで。
・ [^\t]+ は、「最初に見付かったタブで無い文字から続くタブを含まない文字列」にマッチする
・.* は任意の長さ0以上の文字列にマッチする。
これより前は[^\t]+にマッチしているので、この部分は「最初のタブから行末まで」、あるいは、([^\t]+が行全体にマッチしていて残っていない部分の)「空文字列」にマッチする。
・(.*) となっているので、 .* にマッチした部分は \1 で参照できる

となります。

○(g等のフラグを付けない限り) 最初にマッチした部分だけ処理される。
→ [^\t]+がマッチするのは「最初に見付かったタブで無い文字から続くタブを含まない文字列」で、フラグが無いので「同じ行で2回目」にマッチすることはない

○同じ行に対して、1回目マッチと2回目のマッチとでは重複しない
→ .* で行全体にマッチしているので、「その続き」がそもそも残っていない。
    • good
    • 0
この回答へのお礼

ありがとうございます。正規表現は先日一気に学んだものの、sedの流儀が分かっていなかったのですね。すべての疑問が一気に氷解しました。助かりました。

お礼日時:2022/05/11 09:43

このところ sed に触る機会もなくなってるけど, なんかいろいろおかしいような気がする.



まず, そもそもとして
sed -ri "BB/s[^\t]+(.*)/100\1/" sample.txt
ではエラーになるんじゃないかな.

そして「BB と書かれた行の1カラム目」というのは意味が分からない. 「BB と書かれた行」というのは
BB
という行を指すのではないのか?

さらにいえば, これでは「『1カラム目』の『数字』を100に変える」という処理にならない. 例えば
XYZ !<BB this is a pen
という行であっても
100 !<BB this is a pen
になるし, もっというと
\t\t\t\t50 !<BB this is a pen

\t\t\t\t100 !<BB this is a pen
になりそう.
    • good
    • 0
この回答へのお礼

ありがとうございます。おっしゃることは厳密にはそうなのですが、顧客に出すものでもなく、簡単な実験ツールとして使っているだけで、元データは必ず数字で始まるので、エラーになりませんし、厳密性は問いません。

お礼日時:2022/05/11 09:49

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


おすすめ情報