Bash在两个模式之间获取线条并进行编辑

时间:2015-11-07 20:42:31

标签: bash awk grep

我有一个来自dumpsys命令的输出,我想在两个模式之间提取线,Wake Locks&新队。在我获得这些行后,我需要一个特定的字符串。 Wake和Lock不止一次出现在输出中,但Wake Locks:大小只有一次,因此第一个模式可能是"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 = *"和下一个换行符,我可以从中提取pids的格式。也许是这样的:

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

4 个答案:

答案 0 :(得分: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,空行时设置为unset(NF:#of fields = 0)。如果设置了标志迭代字段,并且匹配模式时删除模式以保留搜索到的数字)。字段分隔符设置为空格和逗号,以使用默认分隔符从数字中删除后缀逗号。您可以将结果用于while read pid; do ... done < <(awk ...)或管道到另一个可以处理多行输入的脚本。

答案 1 :(得分:0)

如果我理解你想要正确提取的行,你也可以用bash builtins(参数扩展/子串提取)来完成相同的工作:

#!/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)

答案 2 :(得分:0)

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

\1

编辑:
抱歉,sed可以与-n标志一起使用: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 '/Wake Locks: size=3/,/^$/p'

答案 3 :(得分:0)

使用gawk

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

<强>输出

364345
323345
362505