이런 파일이 있어요
...
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
계속 증가하는 변수로 대체합니다. 단 하나의 패턴이 아닌 일치하는 모든 패턴에서 이 변경을 수행하려는 경우 대신 사용할 수 있습니다.H
H
gsub()
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 -e
file.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>
문자 하나를 삽입합니다. 다른 모든 줄은 약간의 공백만큼 들여쓰기됩니다.
sed
nl
출력은 파이프를 통과했습니다 |
. sed
그런 다음 다음 순서를 바꿉니다.
- 줄 시작 부분에 0개 이상의 숫자가 나타납니다.(로 인용
\1
) - 0개 이상
<tab>
또는<space>
문자 - H가 아닌 문자 0개 이상, 그 다음 문자 1개(로 인용
\2
)
...그리고 \2\1
.
따라서 다음을 포함하지 않는 행은시간다음과 같은 치료를 받으세요:
^'' .*.$ = ^.*.''$
이것을 얻는 사람들은 다음과 같습니다.
^(digit)*<tab>(not H)*H.*$ = ^(not H)*H(digit)*.*$
... ''
빈 문자열이 있습니다.
이식성을 극대화하려면 \t
in을 [ \t]
리터럴 <tab>
문자로 바꿔야 합니다.