删除匹配和上一行

Lev*_*sov 2 regex awk grep sed tr

我需要使用grep,awk,sed或其他东西从流中删除包含"不是动态可执行文件"和前一行的行.我目前的工作解决方案是在整个流中删除新行,然后使用sed替换我匹配之前的换行符,然后使用tr添加新行,然后使用grep -v.用这种方法我有点厌倦了文物,但我不知道我现在还能做些什么:

tr '\n' '|' | sed 's/|\tnot a dynamic executable/__MY_REMOVE/g' | tr '|' '\n'
Run Code Online (Sandbox Code Playgroud)

编辑:

输入是通过管道传输给xargs ldd的混合文件列表,基本上我想忽略关于非库文件的所有输出,因为这与我接下来要做的事情无关.我不想使用lib*.so掩码,因为它可以完全不同

Win*_*ute 5

最简单的是pcregrep在多线模式下:

pcregrep -vM '\n\tnot a dynamic executable' filename
Run Code Online (Sandbox Code Playgroud)

如果pcregrep您无法使用,那么awksed可以通过读取前一行并在标记线出现时跳过前一行的打印来执行此操作.

用awk你可能会很无聊(也很明智):

awk '/^\tnot a dynamic executable/ { flag = 1; next } !flag && NR > 1 { print lastline; } { flag = 0; lastline = $0 } END { if(!flag) print }' filename
Run Code Online (Sandbox Code Playgroud)

那是:

/^\tnot a dynamic executable/ {  # in lines that start with the marker
  flag = 1                       # set a flag
  next                           # and do nothing (do not print the last line)
}
!flag && NR > 1 {                # if the last line was not flagged and
                                 # is not the first line
  print lastline                 # print it
}
{                                # and if you got this far,
  flag = 0                       # unset the flag
  lastline = $0                  # and remember the line to be possibly
                                 # printed.
}
END {                            # in the end
  if(!flag) print                # print the last line if it was not flagged
}
Run Code Online (Sandbox Code Playgroud)

但是sed很有趣:

sed ':a; $! { N; /\n\tnot a dynamic executable/ d; P; s/.*\n//; ba }' filename
Run Code Online (Sandbox Code Playgroud)

说明:

:a                                  # jump label

$! {                                # unless we reached the end of the input:

  N                                 # fetch the next line, append it

  /\n\tnot a dynamic executable/ d  # if the result contains a newline followed
                                    # by "\tnot a dynamic executable", discard
                                    # the pattern space and start at the top
                                    # with the next line. This effectively
                                    # removes the matching line and the one
                                    # before it from the output.

                                    # Otherwise:
  P                                 # print the pattern space up to the newline
  s/.*\n//                          # remove the stuff we just printed from
                                    # the pattern space, so that only the
                                    # second line is in it

  ba                                # and go to a
}
                                    # and at the end, drop off here to print
                                    # the last line (unless it was discarded).
Run Code Online (Sandbox Code Playgroud)

或者,如果文件足够小,可以完全存储在内存中:

sed ':a $!{N;ba}; s/[^\n]*\n\tnot a dynamic executable[^\n]*\n//g' filename
Run Code Online (Sandbox Code Playgroud)

哪里

:a $!{ N; ba }                                  # read the whole file into
                                                # the pattern space
s/[^\n]*\n\tnot a dynamic executable[^\n]*\n//g # and cut out the offending bit.
Run Code Online (Sandbox Code Playgroud)