일치하는 줄의 첫 번째 항목을 모두 증분 숫자로 바꾸는 방법은 무엇입니까?

일치하는 줄의 첫 번째 항목을 모두 증분 숫자로 바꾸는 방법은 무엇입니까?

이런 파일이 있어요

...
1562 first part
1563 H     col3 H col4
1564 H     col3 H col4
...
3241 H     col3 H col4
3242 third part
...

H각 행의 첫 번째 행을 H#해당 #발생 횟수 로 바꾸고 싶습니다 . 출력은 다음과 같아야 합니다.

...
1562 first part
1563 H1    col3 H col4
1564 H2    col3 H col4
...
3241 H1652 col3 H col4
3242 third part
...

지금까지 나는 다음을 시도했습니다.

max=`grep -c ' H ' b`
while [[ "$i" -le $max ]];do
  grep -m $i ' H ' b|tail -n1|sed "s/H/H$i/1"
  let i=i+1
done

이 코드는 느리고 교체할 모든 줄을 읽어야 하며 파일의 첫 번째 부분과 세 번째 부분을 추가하지 못합니다. 이를 수행하는 더 좋은 방법이 있습니까? 어쩌면 어이? 감사해요.

답변1

예를 들어 다음을 사용할 수 있습니다.

$ awk '/H/{sub("H", "H"++v)}1' file
1562 first part
1563 H1     col3 H col4
1564 H2     col3 H col4

3241 H3     col3 H col4
3242 third part
...

그러면 이를 포함하는 행을 찾아 H계속 증가하는 변수로 대체합니다. 단 하나의 패턴이 아닌 일치하는 모든 패턴에서 이 변경을 수행하려는 경우 대신 사용할 수 있습니다.HHgsub()sub()

마지막 조건 1은 true 조건이므로 기본 awk 작업인 {print $0}전체 줄을 인쇄하는 작업을 수행합니다.

답변2

이 시도:

  awk 'BEGIN { hNum = 1; } { if ($2 == "H") { $2 = "H" hNum; hNum++; } print $0; }' yourFile > outFile

각 줄의 두 번째 토큰과 마찬가지로 awk공백을 구분 기호로 사용하여 실행되며 " H"와 같으면 "H"와 1부터 시작하는 숫자로 바꿉니다. 마지막으로 라인을 인쇄하십시오.$2$2

답변3

그리고 perl:

perl -pe 's/\bH\b\K/++$i/e' file

내부 편집으로 -pe대체하거나 원본 파일을 백업으로 저장 하거나 저장하지 않을 수 있습니다 .-pi.back -efile.back-pi -e

답변4

{   nl -bpH -w1 |
    sed 's/^\([0-9]*\)[ \t]*\([^H]*.\)/\2\1/'
} <<\DATA
...
1562 first part 
1563 H     col3 H col4
1564 H     col3 H col4
...
3241 H     col3 H col4
3242 third part
DATA

산출

...
1562 first part 
1563 H1     col3 H col4
1564 H2     col3 H col4
...
3241 H3     col3 H col4
3242 third part

이것은 제가 상상할 수 있는 가장 빠른 방법입니다. 특히 매우 큰 파일의 경우 더욱 그렇습니다. nl문자열을 포함하는 행에 번호만 매기기시간그리고 줄 시작 부분에 해당 숫자를 삽입하고 그 뒤에 <tab>문자 하나를 삽입합니다. 다른 모든 줄은 약간의 공백만큼 들여쓰기됩니다.

sednl출력은 파이프를 통과했습니다 |. sed그런 다음 다음 순서를 바꿉니다.

  • 줄 시작 부분에 0개 이상의 숫자가 나타납니다.(로 인용 \1)
  • 0개 이상 <tab>또는 <space>문자
  • H가 아닌 문자 0개 이상, 그 다음 문자 1개(로 인용 \2)

...그리고 \2\1.

따라서 다음을 포함하지 않는 행은시간다음과 같은 치료를 받으세요:

^''   .*.$ = ^.*.''$

이것을 얻는 사람들은 다음과 같습니다.

^(digit)*<tab>(not H)*H.*$ = ^(not H)*H(digit)*.*$

... ''빈 문자열이 있습니다.

이식성을 극대화하려면 \tin을 [ \t]리터럴 <tab>문자로 바꿔야 합니다.

관련 정보