指定された位置のテキスト変数に文字列を挿入する方法

指定された位置のテキスト変数に文字列を挿入する方法

私は文字列操作のチュートリアルをたくさん見つけましたが、特定の状況に適用する方法がわかりません。文字列変数を挿入(交換ではない)する必要があります。言葉テキスト変数としてテキスト2つの方法のいずれかを使用してください(行番号付けには依存せず、ファイルの読み取り/書き込みよりも変数操作が好ましい)。

  1. 一致する文字列の前または
  2. 特定のインデックス(バイト位置)で

    text="mytextMATCHmytext"
    word="WORD"
    match="MATCH"
    
    # method1 - not working, because text is not a file
    sed '/$word/ i $match' text
    
    # method2
    indx="${text%%$match*}"
    indx=${indx%:*} # leave only the byte index where match starts
    text="$text{0-$index-1}$word$text{$index-end}"
    
    # expected value of text:
    "mytextWORDMATCHmytext"
    

構文を理解するのに役立ちます。両方の方法を修正できれば良いと思います。別の方法がありますか?これテキスト1MB以上のテキストが含まれているので、効率的な方法が好まれます。

答え1

j変数にテキストを挿入するtext場所p(0から計算):

p=5
text="$(seq 10)"               ## arbitrary text
text="${text:0:p}j${text:p}"

j一致する部分の前にテキストを挿入するには、次の手順を実行します$match

text="${text%%${match}*}j${match}${text##*${match}}"

$textこれは、前の部分が見つかるまで引き抜き、$match追加j、追加、および後続の部分が見つかるまで追加します$match。ゲームが1つだけあってほしい!$text$match$match$text

答え2

あなたが言ったように、データがファイルではなく変数にある場合、それはsed直接機能しません。しかし、これは依然として要件を満たす簡単な方法です。パイプを接続するだけです。

#!/usr/local/bin/bash
text="loremipsumNEEDLEdolorsitamet"
word="HAYSTALK"
match="NEEDLE"

echo "$text" | sed "s/$match/&$word/g"

デモ出力:

$ ./369818.sh
loremipsumNEEDLEHAYSTALKdolorsitamet

答え3

この操作を確実に行うには、次の文字列操作ルーチンが必要です。

text_new=${text%%"${match}"*}${word}${text#*"${text%%"${match}"*}"}
#         |------- A -------| |-B--| |------------ C -------------|
  • A事前マッチング部分、つまりマッチングが開始される前の文字列です。
    • 文字列の末尾に立って文字列の先頭を確認し、最後に表示された一致するテキストを削除して含めます。
  • B挿入するデータです。
  • C一致後の部分、つまり一致終了後の文字列です。
    • 文字列の先頭に立って文字列の終わりを見て、ステップAの結果が最初に見える部分を引き裂くことによって生成されます。
  • 一致文字列は、ルーチンがその中のメタ文字を理解しないように引用されていますbash parameter expansion
  • 文字列で一致が複数回発生する可能性を十分に考慮しました。左の最初のゲームが交換されました。
  • 改行文字を含む文字列の場合も処理されます。

match_esc=$(printf '%s\n' "$match" | sed -e 's|[][^\/.*$]|\\&|g' | sed -e 'H;1h;$!d;g;s/\n/\\n/g')
 word_esc=$(printf '%s\n' "$word"  | sed -e 's|[\&/]|\\&|g;$!s/$/\\/')
printf '%s\n' "$text" | sed -e 'H;1h;$!d;g;'"s/$match_esc/$word_esc&/"''
  • このアプローチは、入力テキストに意味があり、入力テキストに表示されるsedすべての文字が無音であることを確認する必要があるため、よりバイパス的です。sedもう1つの複雑さのレベルは、これらの文字がsed s / / /コマンドのLHSとRHSに対して異なることです。
  • 次のステップは、これらの文字を識別して沈黙させることです。
  • その後、一般的なsed //コンテンツを使用してテキストデータを実行するのは簡単です。

関連情報