我試圖在這裡找到一些我可以使用的先前問題,但不幸的是找不到我的確切案例。
我想從另一個命令的輸出中獲得如下所示的結果:
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=1
on lines matching pattern
and c=0
on the rest of the lines and on each line that doesn't start with a digit (as well as in the END
block) check if c
is 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
怎麼運作的:
- 如果當前行以
pattern
then 開頭- 如果我們不在 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