【问题标题】:Bash getting lines between two patterns and editing themBash 在两个模式之间获取线条并对其进行编辑
【发布时间】:2015-11-09 22:08:23
【问题描述】:

我有一个 dumpsys 命令的输出,我想提取两个模式之间的行,唤醒锁和换行符。在我得到这些行之后,我需要一个特定的字符串。 Wake 和 Lock 多次出现在输出中,但 Wake Locks: size 只出现一次,所以第一个模式可能是"Wake*Locks*size"

输出看起来像这样(上面和下面有很多行)

Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)
WAKELOCK 'Term' (uid=35647, pid=362505, ws=null)
#White space

我想要 "Wake Locks: size=*" 和下一个换行符之间的行,格式我可以从中提取 pid。也许是这样的:

for i in `dumpsys power | #Some way to get the desired lines#`; do
Temp=`echo $i | awk '{print $4}'`
$Temp #Assign var pid = number
kill -9 $pid
done

更新

更新后的代码:

dumpsys power | 
sed -n '/Wake Locks: size=/,/^$/ p' |
sed -e 's/.*pid=\([0-9]*\).*/\1/' | 
while read pid; do
    kill -9 ${pid}
done

【问题讨论】:

  • 您显示的行中有三个 PID。你想要哪一个?或者,你想要全部?
  • 每行一个 pid,所以它们都是

标签: bash awk grep


【解决方案1】:

awk 来救援!

$ awk '/Wake Locks: size=/{f=1} !NF{f=0} f' file

会给你

Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)
WAKELOCK 'Term' (uid=35647, pid=362505, ws=null)

如果您只需要 pid 值(有三个,哪一个?)您可以试试这个

awk -v FS="[ ,]" 'f{for(i=1;i<=NF;i++) 
                       if($i~/pid=/) {
                           sub(/pid=/,"",$i);print $i
                        }
                   } 
/Wake Locks: size=/{f=1} 
                !NF{f=0}' file     
364345
323345
362505

说明: 使用模式设置标志 f 并在空行时取消设置(NF:字段数 = 0)。如果设置了标志,则迭代字段,并且当匹配模式时删除模式以保留搜索到的数字)。字段分隔符设置为空格和逗号以使用默认分隔符从数字中删除后缀逗号。您可以在while read pid; do ... done &lt; &lt;(awk ...) 中使用结果,或者将结果传递给另一个可以处理多行输入的脚本。

【讨论】:

  • 所以我必须将输出写入文件并从那里继续,或者管道也在这里工作?您还可以为您的答案添加解释,以供将来参考。
【解决方案2】:

当你在第一行没有匹配时,sed 会做(你可以先检查第一行)。
首先删除 Wake Locks 之前的所有行(以及该行),继续删除剩余流中第一个空行中的所有内容,当您已经在解析时,获取 pid(使用 (\\) 你得到一个记住的字符串,其值用\1打印)。

dumpsys power | sed -e '1,/Wake Locks: size=3/ d' \
                    -e '/^$/,$ d' \
                    -e 's/.*pid=\([0-9]*\).*/\1/' | while read pid; do
   echo "You want to kill ${pid}"
done

编辑:
抱歉,sed 可以与 -n 标志一起使用:sed -n '/Wake Locks: size=3/,/^$/p'
这样你就可以把代码改写成更自然的了

dumpsys power | 
   sed -n '/Wake Locks: size=3/,/^$/ p' |
   sed -e 's/.*pid=\([0-9]*\).*/\1/' | 
   while read pid; do
      echo "You want to kill ${pid}"
   done

【讨论】:

  • 这太完美了!感谢您的回答
【解决方案3】:

如果我理解您希望正确提取的行,您也可以使用 bash 内置函数(参数扩展/子字符串提取)来完成相同的操作:

#!/bin/bash

## read from "$1" or stdin
[ -r "$1" ] && infile="$1" || infile=/dev/stdin

## check line beginnings for each line
while read -r line; do
    [ "${line%%:*}" = "Wake Locks" -o \
    "${line%% *}" = "WAKELOCK_NAME" -o \
    "${line%% *}" = "ANOTHER_WAKELOCK" -o \
    "${line%% *}" = "WAKELOCK_NAME" ] && echo "$line"
done < "$infile"

exit 0

或者使用grep,您可以使用包含您希望在较大文件中匹配的模式的文件并调用grep -f matchfile largefile。在这种情况下,匹配文件可能如下所示:

grep 模式文件

$ cat dat/wakematch.txt
^Wake Locks:
^WAKELOCK_NAME
^ANOTHER_WAKELOCK
^WAKELOCK_NAME

测试输入

$ cat dat/wake.txt
junk and more junk

Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)
WAKELOCK 'Term' (uid=35647, pid=362505, ws=null)
#White space

junk and more junk

Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)
WAKELOCK 'Term' (uid=35647, pid=362505, ws=null)
#White space

使用/输出 - bash 参数扩展/子字符串提取

$ bash wakelock.sh dat/wake.txt
Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)
Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)

$ bash wakelock.sh <dat/wake.txt
Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)
Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)

使用 grep

$ grep -f dat/wakematch.txt dat/wake.txt
Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)
Wake Locks: size=3
WAKELOCK_NAME  'Term' (uid=93847, pid=364345, ws=null)
ANOTHER_WAKELOCK 'Term' (uid=9190247, pid=323345, ws=null)

【讨论】:

    【解决方案4】:

    使用 gawk

    gawk '{if($0~/Wake Locks:/){while( !($0~/^\n$/) && getline >=1){print gensub(/.*pid=([0-9]+).*/,"\\1",$0);}}};'
    

    输出

    364345
    323345
    362505
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-08
      • 1970-01-01
      • 2019-09-28
      • 2023-01-13
      • 2013-05-28
      • 1970-01-01
      • 1970-01-01
      • 2013-06-26
      相关资源
      最近更新 更多