값이 전혀 발견되지 않으면 값이 포함된 새 줄 삽입

값이 전혀 발견되지 않으면 값이 포함된 새 줄 삽입

여기에서 사용할 수 있는 몇 가지 이전 질문을 찾으려고 노력하고 있지만 불행히도 정확한 사례를 찾을 수 없습니다.

다음과 같은 다른 명령의 출력을 얻고 싶습니다.

pattern.d
17.91
17.55
pattern.b
pattern.a
7.21
9.34
pattern.c

이에:

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

좀 더 설명하겠습니다. "pattern" 문자열이 포함된 모든 줄 뒤에는 항상 숫자가 있어야 합니다. 그렇지 않은 경우 값이 1000인 새 줄을 삽입하고 싶습니다.

패턴에는 다양한 "확장자"(.a .b .c .d이지만 "확장자"의 숫자는 없음)가 있으며 나중에 내용을 알파벳순으로 정렬하는 데 도움이 됩니다.

편집: 답변을 수락했지만 누군가가 여전히 다른 변형을 찾고 싶어하는 경우 "패턴"의 발생이 다양하며 다음과 같이 2~3개 이상의 연속 패턴이 있을 수 있음을 지정해야 합니다.

pattern.a
pattern.d
pattern.c
pattern.d
pattern.b
17.91

답변1

다음은 sed모든 입력에서 작동하는 솔루션입니다(예: 여러 개의 연속 행 일치 pattern).

sed '1{                   # when on first line
x                         # exchange
s/^/1000/                 # replace the empty hold buffer with "1000"
x                         # exchange back
}
: do                      # label "do"
/pattern/{                # if the current line matches "pattern"
${                        # if we're on the last line
G                         # append hold buffer content to pattern space
b                         # go to end of script
}
n                         # otherwise print and pull in the next line
/^[[:digit:]]/!{          # if this one doesn't start with a digit
x                         # exchange
p                         # print (the pattern space is now "1000")
x                         # exchange back
b do                      # go to label "do"
}
}' infile

그것 으로 gnu sed다음과 같이 쓸 수 있습니다.

sed '1{x;s/^/1000/;x};:b;/pattern/{${G;b};n;/^[[:digit:]]/!{x;p;x;bb}}' infile

다음과 비슷한 작업을 수행할 수 있습니다 awk.

awk -vc=0 '!/^[[:digit:]]/{
if (c) {print "1000"}
}
{ if (/pattern/){c=1} else{c=0}
}
END{if (c){print "1000"}
};1' infile

즉, c=1일치하는 줄 patternc=0나머지 줄 및 숫자로 시작하지 않는 각 줄(블록에서도 마찬가지 END) 에 c설정되어 있는지 확인합니다(또는 1이전 줄이 일치함을 의미 pattern). 그렇다면 인쇄하다 1000.

답변2

sed -e '
   $!{
      /pattern\.[a-z]/N
      /\n/!b
      /\n[+-]\{0,1\}[.][0-9]\{1,\}$/b
      /\n[+-]\{0,1\}[0-9]\{1,\}\([.][0-9]*\)\{0,1\}$/b
      h;s/\(.*\n\).*/\11000/p
      g;D
   }
   /pattern\.[a-z]/a\
1000
' yourfile

결과

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

일하고 있는

  • eof가 아닌 동안 $!{...}현재 줄이 관심 있는 줄이라는 조건으로 패턴 공간에 다음 줄을 추가합니다.
  • 그런 다음 다음과 같은 경우 추가 처리를 건너뜁니다. a) 개행을 찾을 수 없음 => 현재 줄에 패턴이 없습니다. b) 두 번째 줄에는 .nnn 형식의 부동 소수점 숫자. c) mmm, mmm. 또는 mmm.nnn 형식의 부동 소수점 숫자는 두 번째 줄에서만 발견됩니다. d) 가능성이 있는 경우를 제외하고 => 개행 문자 다음 줄의 끝에 매직 넘버 1000을 추가해야 합니다.

답변3

의 연속 인스턴스가 2개 이상 없고 patternGNU sed가 있는 경우:

sed '/^pattern/ {$!N; /\n[0-9]/b; s/$/\n1000/M}' file
pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

작동 방식:

  • 현재 줄이 patternthen 으로 시작한다면
    • EOF가 아닌 경우 다음 줄을 추가하십시오.
    • 줄 바꿈 뒤에 숫자가 있으면(더 구체적으로 만들 수 있음) b밖으로 나가십시오(즉, 다음 줄로 계속). 또 다른
    • 개행 문자로 끝나는 첫 번째 줄을 대체하고1000

GNU 특정 M수정자는 "일반" 사례와 다음 줄이 추가되지 않는 EOF 사례를 모두 처리하도록 또는 $일치를 허용합니다.\n$

답변4

해결책:

awk '{ if ($0 ~ /pattern/) {      # if it's a `pattern` line
         if ((getline nl) > 0) {  # check if next record exists
             # if next record hasn't number - insert `1000`, otherwise - print current and next records as they are
             print ((nl !~ /^[0-9]/)? $0 ORS 1000 ORS nl: $0 ORS nl)
         } else {
             print $0 ORS 1000   # if the file ends up with pattern - insert `1000`
         } 
       } else {
          print $0  # print other record
       }
    }' file

출력:

pattern.d
17.91
17.55
pattern.b
1000
pattern.a
7.21
9.34
pattern.c
1000

관련 정보