텍스트의 숫자가 연속적이지 않은 경우 일부 기호(또는 개행 문자)를 추가하는 방법

텍스트의 숫자가 연속적이지 않은 경우 일부 기호(또는 개행 문자)를 추가하는 방법

전임자:

입력 파일

A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
A_D2<6>
A<9>
A_D2<10>
A<13>

원하는 출력:

A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
-----
A_D2<6>
-----
-----
A<9>
A_D2<10>
-----
-----
A<13>

꺾쇠괄호 안의 숫자만 주의하세요.

숫자가 연속되지 않으면 숫자가 다시 연속될 때까지 일부 기호를 추가하거나 개행만 추가하세요.

이 예에서는 숫자 5, 7, 8, 11, 12가 누락되었습니다.

누구든지 awk 또는 sed(또는 심지어 grep) 명령을 사용하여 이 문제를 해결할 수 있습니까?

저는 리눅스 초보자입니다. 전체 명령줄에 대해 자세히 설명해주세요.

답변1

grep계산할 수 없고 위험하므로 사용하거나 수행하지 않는 것이 좋습니다 .sedgrepsed정말 힘들다모든 종류의 산술을 수행합니다(정규식 기반 계산이어야 하며, 이는 다음을 제외하고 대부분의 사람들에게 불가능합니다).저주 받은).

$ awk -F '[<>]' '{ while ($2 >= ++nr) print "---"; print }' file
A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
---
A_D2<6>
---
---
A<9>
A_D2<10>
---
---
A<13>

코드에서는 이 숫자가 첫 번째 숫자여야 한다고 awk가정 한 다음 유지합니다.0구함변수에 있는 현재 줄의 줄 번호입니다 nr. 입력에서 숫자를 읽으려면 하나 이상의 행을 삽입해야 하는 경우 루프를 사용하여 수행됩니다 ( 변수 while도 증가함 ).nr

입력된 숫자는 <...>지정된 대로 구문 분석되며 <필드 >구분자로 사용해야 합니다. 숫자는 $2(두 번째 필드)에 있습니다.

답변2

이것은 아마도 효율적이지 않을 것입니다 ...

$ tr '<' '\t' < testfile | tr '>' ' ' \
  | awk '{ while (NR + shift <= $2) { print "-----"; shift++ }; print }' \
  | tr '\t' '<' \
  | tr ' ' '>'
A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
-----
A_D2<6>
-----
-----
A<9>
A_D2<10>
-----
-----
A<13>

tr먼저, 저는 파일에서 탭으로 구분된 두 개의 필드를 가져오곤 했습니다 .

둘째, tr'>'를 다시 공백으로 바꿨습니다. 그렇지 않으면 awk 명령이 실패할 것이기 때문입니다. :-/

여기 awk 프로들은 아마 지금 웃고 있을 거예요 :-)

셋째, awk- 명령은 처리된 행 수를 두 번째 필드와 비교합니다. 행 수가 더 적으면 표시를 인쇄하고 표시하는 증분을 shift이전에 비교한 행 수에 추가합니다.

넷째, 다섯째: 이전 사용을 취소합니다 tr.

나는에게서 영감을 얻었습니다.https://unix.stackexchange.com/a/190707/364705

답변3

저는 awk남자는 아니지만 이것이 효과가 있는 것 같습니다. 나는 항상 개선에 열려 있습니다.

awk -F '[<>]' -v num=0 '
{
  while(num < $2) {
    print "----";
    num++
  }
  print $1"<"$2">"
  num++
}' file

먼저 및 문자 <와 일치하도록 필드 구분 기호를 설정하여 >각 행이 이러한 문자로 분할됩니다. 예를 들어 첫 번째 행은 $1=A및 에 할당됩니다 $2=0.

그런 다음 변수를 설정합니다 num=0. 이것을 행 카운터로 사용합니다. 현재 행 수가 $2행 카운터보다 크면 인쇄하고 ----카운터를 증가시키고 두 값이 동일해질 때까지 반복합니다. 그런 다음 $1<$2>카운터를 인쇄 하고 증가시킵니다.

답변4

정규식을 통해 미리보기 및 뒤돌아보기를 사용하고 대시만 추가하여 이 문제를 해결할 수 있습니다.

$ perl -0777 -pe 's/^.*<(\d+)>.*\n\K(?=.*<(\d+)>.*$)/qq[-----\n] x ($2-$1-1)/gem' file

결과:

A<0>
A<1>
A_D2<2>
A_D2<3>
A<4>
-----
A_D2<6>
-----
-----
A<9>
A_D2<10>
-----
-----
A<13>

관련 정보