안녕하세요, 저는 패턴/단어 문자열에서 텍스트 파일의 한 줄을 선택하고 해당 줄을 새 텍스트로 바꾸고 각 줄 변경에 대해 숫자를 증가시키는 방법을 알아내려고 합니다.
sed를 사용할 계획이지만 각 행 변경에 대해 증가하는 숫자를 구현하는 방법을 모르겠습니다.
목표 전후:
이전 텍스트:
">text_1_lots of other bits of text"
other lines of text
">text_2_lots of other bits of text"
other lines of text
">text_3_lots of other bits of text"
other lines of text
다음 텍스트:
">text_1"
other lines of text
">text_2"
other lines of text
">text_3"
other lines of text
이것이 내가 지금까지 가지고 있는 것입니다:
sed -i "s/>text_*/>text_[0-n]/g"
[0-n]
및 와일드카드는 *
내가 하고 싶은 일을 나타내고 이를 달성하기 위해 생각할 수 있는 가장 가까운 것이기 때문에 이것이 작동하지 않는다는 것을 알고 있습니다 (비록 이것이 본질적으로 의사 코드라는 것을 알고 있지만).
답변1
perl
sed
이는 대체 인덱스를 직접 평가하는 것과 유사하지만 허용하는 구문을 사용하여 수행할 수 있습니다 .
perl -pe 's/>text_.*/sprintf "text_%d", ++$n/pe' file
당신은 또한 볼 수 있습니다문자열을 순차 인덱스로 교체.
그러나 귀하의 경우 텍스트에 이미 번호가 매겨져 있으므로 불필요한 부분을 캡처하고 다시 교체하여 잘라내는 것이 더 쉬울 것입니다.
sed -E 's/(>text_[0-9]+).*/\1/' file
답변2
sed를 사용한 시도에 따르면 일치시키려는 패턴은 다음 ">text_
과 같 으며 "
숫자와
이것을 사용할 수 있습니다 awk
.
awk 'BEGIN {cnt=1} /^">text_/ { gsub("_.*$","_"cnt++"\"",$0) } { print}'
예를 들어
$ cat x
">text_lots of other bits of text"
other lines of text
">text_lots of other bits of text"
other lines of text
">text_lots of other bits of text"
other lines of text
$ awk 'BEGIN {cnt=1} /^">text_/ { gsub("_.*$","_"cnt++"\"",$0) } { print}' x
">text_1"
other lines of text
">text_2"
other lines of text
">text_3"
other lines of text
^"text_
변경하려는 행을 식별하기 위해 검색 모드를 변경할 수 있으며 이 경우 행의 gsub()
처음 부터 끝까지 교체된 다음 계산 됩니다._
_
"
답변3
가장 쉬운 방법은 bash나 Perl을 사용하는 것입니다. 간단한 bash 예제는 잠재적으로 더 복잡한 문제를 해결하는 데 도움이 됩니다.
$ cat script
#!/bin/bash
i=1
while read a ; do
if [[ "$a" =~ "\">text_${i}".* ]]
then echo "\">text_${i}\"" ; i=$((i+1))
else echo "$a"
fi
done
$ cat input
">text_1_lots of other bits of text"
other lines of text
">text_2_lots of other bits of text"
other lines of text
">text_3_lots of other bits of text"
other lines of text
$ cat input | bash script
">text_1"
other lines of text
">text_2"
other lines of text
">text_3"
other lines of text
답변4
사용행복하다(이전 Perl_6)
~$ raku -pe 'state $i; s/^ \" \> text_ .* /"text_{++$i}"/;' file
또는:
~$ raku -pe 'state $i; s/^ \" \> text_ .* /{sprintf "\"text_%d\"", ++$i}/;' file
Raku는 Perl 계열의 프로그래밍 언어입니다. 위의 두 번째 답변은 기본적으로 @steeldriver의 뛰어난 Perl5 코드를 번역한 것입니다.
즉, -pe
Raku의 sed와 유사한 자동 인쇄 명령줄 플래그가 사용됩니다. Raku 정규식의 문자가 아닌 문자는 <alnum>
이스케이프해야 하지만 정규식 원자는 공백을 허용할 수 있기 때문에 확장될 수 있습니다(Perl의 와 동일 \x
). 카운터 변수 는 d $i
입니다 state
. 이는 한 번만 인스턴스화된다는 의미입니다(예를 들어 여기서 BEGIN 블록을 사용할 수 있음 BEGIN my $i;
). 대체는 설명이 필요합니다. Raku 코드는 {
... }
중괄호 안에 삽입됩니다.
입력 예:
">text_A_lots of other bits of text"
other lines of text
">text_B_lots of other bits of text"
other lines of text
">text_C_lots of other bits of text"
other lines of text
예제 출력:
"text_1"
other lines of text
"text_2"
other lines of text
"text_3"
other lines of text
https://docs.raku.org/언어/regexes
https://docs.raku.org
https://raku.org