當根本找不到值時插入包含值的新行

當根本找不到值時插入包含值的新行

我試圖在這裡找到一些我可以使用的先前問題,但不幸的是找不到我的確切案例。

我想從另一個命令的輸出中獲得如下所示的結果:

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

that is, set c=1on lines matching patternand c=0on the rest of the lines and on each line that doesn't start with a digit (as well as in the ENDblock) check if cis set (or 1- meaning the previous line matches pattern) - if so列印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

如果 的連續實例絕對不會超過兩個pattern,而您有 GNU 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修飾符允許$匹配 or \n$以便它處理「正常」情況和 EOF 情況(不附加後續行)。

答案4

awk解決方案:

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

相關內容