지정된 위치의 텍스트 변수에 문자열을 삽입하는 방법

지정된 위치의 텍스트 변수에 문자열을 삽입하는 방법

문자열 조작 튜토리얼을 많이 찾았지만 특정 상황에 적용하는 방법을 모르겠습니다. 문자열 변수를 삽입(교체 아님)해야 합니다.단어텍스트 변수로텍스트두 가지 방법 중 하나를 사용하십시오(줄 번호 매기기에 의존할 수 없으며 파일 읽기/쓰기보다 변수 조작이 선호됩니다).

  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. 게임이 하나만 있었으면 좋겠어요!$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또 다른 복잡성 수준은 이러한 문자가 sed s/// 명령의 LHS 및 RHS에 대해 다르다는 것입니다.
  • 다음 단계는 이러한 문자를 식별한 다음 침묵시키는 것입니다.
  • 그 후에는 일반적인 sed s/// 내용을 사용하여 텍스트 데이터를 실행하는 것이 간단합니다.

관련 정보