sedの挿入モードを文字列の途中に適用するのを避けるには?

sedの挿入モードを文字列の途中に適用するのを避けるには?

目的

目的は、次の文字列を変換することです。

hello_hello,123-world567-helloworld123456,world1234-hello09876

特定の形式に変換するには、sedを使用してください。

努力する

sed -e 's|^\(hello_[a-z0-9]\{3\}\)\(.*\)|\1,\1\2|g;s|..|&/|g' /tmp/file

予想される結果

he/ll/o_/he/ll/o,123-world567-helloworld123456,/wo/rl/d1/23/4-/he/ll/o0/98/76/

現在の結果

問題は、/2文字ごとにaが挿入されることです。/2 つのカンマ間の挿入を避けてください。

he/ll/o_/he/ll/o,/12/3-/wo/rl/d5/67/-h/el/lo/wo/rl/d1/23/45/6,/wo/rl/d1/23/4-/he/ll/o0/98/76/

ベストアンサー1

私はこれを行うことができます:

sed 's|\(,[^,]*,\)\{0,1\}\([^,]\{1,2\}\)|\1/\2|g
' <<\IN                                     
hello_hello,123-world567-helloworld123456,world1234-hello09876
IN

...印刷...

/he/ll/o_/he/ll/o,123-world567-helloworld123456,/wo/rl/d1/23/4-/he/ll/o0/98/76

だから最大2番目の代替項目が変更されましたs///。しかし、これは最初の代替項目をすべて削除したためです。

したがって、問題の最大の部分は、2文字ごとに1つずつsed変更するように言うことです/.。点は次のことを意味します。すべての文字そしてgグローバルな意味 - またはみんな

2番目に重要なのは、最初の代替は役に立たず、完全に不要であるということです。

また、最初の交換に追加のカンマを挿入しました。したがって、最初のビットを見つけた後も、まだ追加のフィールドが発生しました。望むより:

\(,[^,]*,\)\{0,1\}\([^,]\{1,2\}\)|\1/\2

これは私にとって適切な代替説明であり、その理由は次のとおりです。

  • \(,[^,]*,\)\{0,1\}- グローバルには気をつけて必要な分だけ受け取らなければなりません。 2文字ごとに置き換えたので、次のような結果が得られますsed貪欲。これを最初に引用することが重要です。なぜならsed、左から右に読み取るとき、通常はカンマではなく2つの連続した文字の間にスラッシュが挿入されるからです。ただし、カンマが見つかった場合は、次のコンマを読み、保存します。\1スラッシュをまったく挿入せずにブロック全体を削除します。

  • \([^,]\{1,2\}\)- ここではドットは使用できません.。カンマと一致するので、区切り文字をスキップしてスラッシュを入力するだけです。コンマを明示的に除外する必要があります。それがすることです - 1つまたは2つのシーケンスごとに -sed常に可能な最大数を取得します。

この例とあなたの例の間で私が見ることができる1つの違いは、ここで最初のスラッシュが文字列の先頭にあり、末尾のスラッシュがないことです。一方、あなたの例では逆です。必要に応じてこの問題を解決するには、次の手順を実行します。

...;s|^/\(.*/.\)/*$|\1/|...

おすすめ記事