我有以下一组需要通过sed处理的字符串:
start-pattern
[SYSTEM] capture ............................... FAIL [ 2.825 s]
[SYSTEM] capture ............................... FAIL [ 2.825 s]
[DEBUG] capture :: capture :: capture .......... FAIL [ 0.866 s]
[DEBUG] capture :: me :: capture capture capture FAIL [ 0.876 s]
[DEBUG] capture-me ............................. FAIL [ 0.361 s]
end-pattern
我想写一个sed表达式(如果可能的话,最好使用sed)来获取[DEBUG]
||之间的所有字符串失败的测试用例的每一行都有[SYSTEM]
和FAIL [.*]
,文本{start,end} -pattern之间的空格和句点
.
除外。
上述文字的输出应为以下一项或多项:
capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me
这是我尝试过的,但不适用于所有行:
sed -e 's/\[DEBUG\] \(.*\) :: \(.*\) :: \(.*\) \([^.]FAIL \[.*\]) \[.*/\1::\2::\3::\4/' -e 's/\[SYSTEM\] \(.*\) \..*/\1/'
答案 0 :(得分:3)
以下是如何在任何UNIX系统上以清晰,简单,健壮,高效和便携的方式执行的操作:
$ cat tst.awk
/start-pattern/ { inBlock=1 }
inBlock {
if ( sub(/^\[(DEBUG|SYSTEM)\]/,"") && sub(/FAIL.*/,"") ) {
gsub(/[[:space:].]/,"")
print
}
}
/end-pattern/ { inBlock=0 }
$ awk -f tst.awk file
capture
capture
capture::capture::capture
capture::me::capturecapturecapture
capture-me
请注意,您说您想要输出excluding spaces and period .
,因此上面的" capture"之间没有空格。如果您真正想要的只是排除::
周围的空格以及输出行的开头/结尾,那么这只是一个调整:
$ cat tst.awk
/start-pattern/ { inBlock=1 }
inBlock {
if ( sub(/^\[(DEBUG|SYSTEM)\]/,"") && sub(/FAIL.*/,"") ) {
gsub(/[[:space:]]*::[[:space:]]*/,"::")
gsub(/^[[:space:]]+|[[:space:]]+$|[.]/,"")
print
}
}
/end-pattern/ { inBlock=0 }
$ awk -f tst.awk file
capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me
答案 1 :(得分:1)
您可以使用以下内容:
$ gsed -nE 's/\[(DEBUG|SYSTEM)\] (.*) FAIL.*/\2/;{s/[.]//g;s/ :: /::/g;p;}' file
capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me
-n
选项自动停止sed
打印行,-E
启用扩展正则表达式(此选项记录为-r with GNU sed -E
适用于GNU和BSD sed)。
s # Substitution command
/ # Start of match
\[ # Match a literal [
(DEBUG|SYSTEM) # Match DEBUG OR SYSTEM
\] # Match a literal ] followed by a space
(.*) # Match everything after and capture it
FAIL.* # Match a FAIL and everything after
/ # Stop match and start replacement
\2 # Replace with the second capture group
{ # If substitution matched applied following commands
s/[.]//g; # Global substitution of literal .
s/ :: /::/g; # Global substitution of spaces around literal ::
p; # Print the result
}
答案 2 :(得分:1)
这对我来说对样本输入有用:
data FixMePls a = FixMe | Pls a deriving (Eq, Show)
instance Monoid a => Monoid (FixMePls a) where
mempty = Nothing
mappend m Nothing = m
mappend Nothing m = m
mappend (Pls a) (Pls a') = Pls (mappend a a')
instance Applicative FixMePls where
pure = Pls
Nothing <*> _ = Nothing
_ <*> Nothing = Nothing
Pls f <*> Pls a = Pls f a
main :: IO ()
main = do
putStrLn("Weee!!!1!")
sed -nE '/^.*\[(SYSTEM|DEBUG)\] *(.*[^ ]) *FAIL.*$/{;s//\2/;s/[.]//g;p;}'
说&#34;不要打印每一行&#34; -n
启用扩展正则表达式(与-E
交替时需要;没有它,即使|
也不可用)\|
匹配我们正在寻找的每一行的所有 /^.*\[(SYSTEM|DEBUG)\] *(.*[^ ]) *FAIL.*$/
开始一系列以分号分隔的命令以应用于匹配行{
表示要替换与前一个正则表达式匹配的内容,只更换第二组s//\2/
之间匹配的部分... (
)
删除所有期间。s/[.]//g
打印出p
终止该块。答案 3 :(得分:1)
这也是一项工作:
sed -n -e '/^\[SYSTEM\]/ ba; /^\[DEBUG\]/ ba; b;'
-e ':a s/^\[.*\]\(.*\)FAIL.*/\1/; s/[ \.]*//g; \
:c s/\(capture\)\(capture\)/\1 \2/g; tc; p;'
testcases.txt
输出:
capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me
如果该行以[SYSTEM]
或[DEBUG]
开头,则采用分支并完成替换并打印出结果。否则什么也没做。
由于要求(在问题描述中未提及,但是由希望的输出隐式给出),还有另一种构造可以在两次连续捕获之间保留空白。
更详细:
1。)-n
:如果没有p
命令明确强制,则不打印模式空间。
2。)ba
:跳转到标签a
。
3。)b
:跳到脚本结尾。
4。)tc
:如果已经进行了成功的替换,则跳转到标签c
(自上次使用后读入最后一行并自上次使用t
起,T
)。
答案 4 :(得分:1)
使用以下sed
命令组合:
sed -En 's/^\[(DEBUG|SYSTEM)\] (.+) FAIL.*$/\2/p' testfile | sed -En 's/(\.|\s(::)\s)/\2/gp'
输出:
capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me
第二个命令s/(\.|\s(::)\s)/\2/gp
将删除所有点.
,并将' :: '
替换为其修剪值::
缩短的版本如下:
sed -En 's/^\[(DEBUG|SYSTEM)\] (.+) FAIL.*$/\2/;s/(\.|\s(::)\s)/\2/gp' testfile
答案 5 :(得分:1)
awk -F'[]F]' '{gsub(/\./,"")gsub(/ /,"")gsub(/ec/,"e c");print $2}' file
capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me