파일에서 마지막으로 일치하는 검색어 앞에 텍스트를 추가하세요.

파일에서 마지막으로 일치하는 검색어 앞에 텍스트를 추가하세요.

여러 파일에서 특정 단어(예제에서는 SearchWord)가 마지막으로 나타나기 전에 몇 줄의 텍스트를 추가해야 합니다.

  • 검색은 대소문자를 구분해야 합니다.
  • 해당 단어는 파일의 여러 줄에 나타납니다.

파일의 기존 데이터

SearchWord abc defgh
SEARCHWORD abc1234
sEarchWord abcd
sometext 1
sometext 2

원하는 출력

SearchWord abc defgh
SEARCHWORD abc1234 
NEWLINE_1_ADDED
NEWLINE_2_ADDED
NEWLINE_3_ADDED
sEarchWord abcd
sometext 1
sometext 2

답변1

exPOSIX 파일 편집기 사용

ex파일 편집기의 비시각적 형태입니다 vi. 실제로는 vi. vi(및 Vim) 이전에도 여전히 ex명령을 사용합니다. 콜론을 입력하고 명령을 입력할 때마다 이는 명령입니다 ex(Vim에는 많은 사용자 정의 확장이 있지만).

ex개봉 이후모두Sed 또는 Awk와 달리 주소 지정은 스트림에서 작동하는 대신 앞뒤로 발생할 수 있습니다.

이 특정 편집의 경우 다음 줄을 사용하십시오.

printf '%s\n' 'set ignorecase' '$+?searchword?i' 'NEWLINE_1_ADDED' 'NEWLINE_2_ADDED' 'NEWLINE_3_ADDED' . x | ex input.txt

명령을 테스트하려면(파일에 저장하는 대신 표준 출력으로 인쇄) 최종 명령으로 %p대신 사용하십시오.x

printf '%s\n' 'set ignorecase' '$+?searchword?i' 'NEWLINE_1_ADDED' 'NEWLINE_2_ADDED' 'NEWLINE_3_ADDED' . %p | ex input.txt 

여러 파일 처리:

for f in *.txt; do
    printf '%s\n' 'set ignorecase' '$+?searchword?i' 'NEWLINE_1_ADDED' 'NEWLINE_2_ADDED' 'NEWLINE_3_ADDED' . x | ex "$f"
done

설명하다

명령 자체를 실행하면 printf다음 명령이 전달되는 것을 볼 수 있습니다 ex.

set ignorecase
$+?searchword?i
NEWLINE_1_ADDED
NEWLINE_2_ADDED
NEWLINE_3_ADDED
.
x

명령 set은 설명이 필요 없습니다.

$+라인을 가리킨다뒤쪽에마지막 줄은 ?...?거기에서 뒤로 검색하는 것을 나타냅니다. (이렇게 하면 +마지막 줄이 일치하는 파일이 올바르게 처리될 수 있습니다.) i텍스트 "삽입"을 의미합니다.앞으로라인을 찾아보세요.

.자체는 삽입할 텍스트를 끝냅니다.

x저장 및 종료.

답변2

다음 줄을 텍스트 파일에 저장한 infile다음 파일을 제자리에서 편집하는 데 사용하면 ed더 쉬울 것입니다 .

for f in ./*.txt; do
ed -s "$f" <<\IN
.t.
?[kK][eE][yY][wW][oO][rR][dD]?-1 r infile
$d
w
q
IN
done

파일 내용이 아닌 일부 텍스트만 삽입하려면 다음과 같이 하세요.

for f in ./*.txt; do
ed -s "$f" <<\IN
.t.
?[kK][eE][yY][wW][oO][rR][dD]?-1 s/$\
some_text\
more_text\
last\\_\&_line
$d
w
q
IN

파일을 수정하지 않고 수행되는 작업을 보려면 w다음으로 바꾸십시오 . 백슬래시, 앰퍼샌드 및 구분 기호는 대체 항목의 오른쪽에서 이스케이프되어야 합니다. 마지막 줄을 제외하고 개행에도 동일하게 적용됩니다. 어떻게 작동하나요? 마지막 줄을 복사하고, 뒤로 키워드를 검색하고, 줄 앞에 텍스트나 파일 내용을 삽입하고, 마지막 줄의 중복을 제거하고, 쓰고 종료하세요.,p


물론, 이러한 파일을 내부에서 편집할 필요가 없고 수정된 버전만 인쇄하려는 경우에는 다음과 같습니다.자나다른 시대의 구문을 사용하는 신비한 텍스트 편집기가 필요하지 않다는 것은 사실입니다. sed단 한 번의 호출로 이를 수행할 수 있습니다.와일드카드참고로, 이 편집기 시리즈에는 i일치하기 전에 텍스트를 삽입하는 전용 명령이 있습니다. 이를 사용하고 일부 분기를 사용해 보겠습니다.

sed -s '1{h;$!d;b end
}
/keyword/I{H;$!d
}
//{x;p;$!d
}
:end
${x;/keyword/Ii\
some_text_here\
more_text_here\
and_a\\_backslash
}' ./*.txt

이것은 작동합니다 gnu sed... 다른 seds의 경우 루프를 실행해야 합니다(이번에는 분기 부분이 없으므로 각 파일 내용 사이에 빈 줄이 있습니다).

for f in ./*.txt; do
sed -s '/[kK][eE][yY][wW][oO][rR][dD]/{H;$!d
}
//{x;p;$!d
}
${x;/[kK][eE][yY][wW][oO][rR][dD]/i\
some_text_here\
more_text_here\
and_a\\_backslash
}' "$f"
done

보시다시피 i, nsert를 사용해도 백슬래시와 개행 문자는 여전히 이스케이프되어야 합니다(마지막 항목 제외). 그 외에는 간단합니다. 홀드 버퍼에 라인을 축적하고 마지막 라인에서 일치하는 항목이 발견되면 교체하고, 다시 교체하여 일치하는 항목(있는 경우) 앞에 텍스트를 삽입합니다.

답변3

tacGNU가 있다면 sed사용할 수 있습니다

$ tac file | sed '0,/searchword/I s/.*searchword.*/&\nNEWLINE_3_ADDED\nNEWLINE_2_ADDED\nNEWLINE_1_ADDED/I' | tac
SearchWord abc defgh
SEARCHWORD abc1234
NEWLINE_1_ADDED
NEWLINE_2_ADDED
NEWLINE_3_ADDED
sEarchWord abcd
sometext 1
sometext 2

설명하다

  • tac파일을 거꾸로 인쇄
  • 0,/pattern/패턴이 처음 나타나는 경우에만 작동
  • I대소문자를 구분하지 않는 검색
  • s/old/new/old사용. . . 교체new
  • .*searchword.*다음을 포함하는 전체 줄과 일치합니다.searchword
  • &일치하는 패턴 전체를 다음에서 교체합니다.
  • \n새로운 팀

아마도 더 읽기 쉬울 것입니다.

tac file | sed '0,/searchword/I s/.*searchword.*/&\
NEWLINE_ADDED_3\
NEWLINE_ADDED-2\
NEWLINE_ADDED_1/I' | tac

관련 정보