bash排序和格式化文本输出

时间:2014-04-22 18:00:03

标签: bash sorting awk sed

我是bash脚本新手,

我需要格式化这个文本,它有几个数据,我需要的是将类似的应用程序分组为它的PID以获得每个应用程序到不同数据库的总连接。

Text 1.txt

App: App_1 PID: 27996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
App: App_1 PID: 27996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 12
App: App_1 PID: 27996 DBsrv: DBSRV_3 IP: 1.2.3.3 Current: 3
App: App_1 PID: 23996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 10
App: App_1 PID: 23996 DBsrv: DBSRV_5 IP: 1.2.3.5 Current: 12
App: App_3 PID: 25996 DBsrv: DBSRV_7 IP: 1.2.3.7 Current: 15
App: App_3 PID: 27196 DBsrv: DBSRV_8 IP: 1.2.3.8 Current: 16
App: App_3 PID: 27196 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 12
App: App_2 PID: 28996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
App: App_2 PID: 28996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 19
App: App_4 PID: 21996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
App: App_5 PID: 20996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 1
App: App_5 PID: 20996 DBsrv: DBSRV_1 IP: 1.2.3.4 Current: 1

期望的输出:

App: App_1 PID: 27996
App: App_1 PID: 27996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
App: App_1 PID: 27996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 12
App: App_1 PID: 27996 DBsrv: DBSRV_3 IP: 1.2.3.3 Current: 3
--
App: App_1 PID: 23996
App: App_1 PID: 23996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 10
App: App_1 PID: 23996 DBsrv: DBSRV_5 IP: 1.2.3.5 Current: 12
--
App: App_3 PID: 25996 
App: App_3 PID: 25996 DBsrv: DBSRV_7 IP: 1.2.3.7 Current: 15
--
App: App_3 PID: 27196
App: App_3 PID: 27196 DBsrv: DBSRV_8 IP: 1.2.3.8 Current: 16
App: App_3 PID: 27196 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 12
--
App: App_2 PID: 28966
App: App_2 PID: 28996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
App: App_2 PID: 28996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 19
--
App: App_4 PID: 21966
App: App_4 PID: 21996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
--
App: App_5 PID: 20966
App: App_5 PID: 20996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 1
App: App_5 PID: 20996 DBsrv: DBSRV_1 IP: 1.2.3.4 Current: 1

6 个答案:

答案 0 :(得分:2)

您可以使用此awk脚本:

awk 'p!=$4{c=$4;print "App: "$2" PID "p}1' data.txt

脚本检查PID的内容是否发生变化。如果是,则打印标题并将新的PID值放入变量p - pid。所有行都将打印在awk只有1,因为1评估为true,而print是awk中的默认每行操作。


我看到上面的命令缺少--分隔符。您可以稍微修改它以实现它。我添加了一个新变量s - 分隔符。它将在标题之前打印,除非它是第一行,因为s在打印第一个标题后被初始化并且在之前为空:

awk 'p!=$4{p=$4;print s"App: "$2" PID "p;s="--\n"}1' data.txt

答案 1 :(得分:1)

你可以这样做:

awk '
BEGIN { SUBSEP = FS }
{
    pids[$1,$2,$3,$4] = ((pids[$1,$2,$3,$4]) ? pids[$1,$2,$3,$4] RS $0 : $0)
}
END {
    for(pid in pids) {
        print pid; print pids[pid]
    }
}' file

App: App_2 PID: 28996
App: App_2 PID: 28996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
App: App_2 PID: 28996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 19
App: App_3 PID: 27196
App: App_3 PID: 27196 DBsrv: DBSRV_8 IP: 1.2.3.8 Current: 16
App: App_3 PID: 27196 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 12
App: App_1 PID: 27996
App: App_1 PID: 27996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
App: App_1 PID: 27996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 12
App: App_1 PID: 27996 DBsrv: DBSRV_3 IP: 1.2.3.3 Current: 3
App: App_4 PID: 21996
App: App_4 PID: 21996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 1
App: App_3 PID: 25996
App: App_3 PID: 25996 DBsrv: DBSRV_7 IP: 1.2.3.7 Current: 15
App: App_5 PID: 20996
App: App_5 PID: 20996 DBsrv: DBSRV_2 IP: 1.2.3.2 Current: 1
App: App_5 PID: 20996 DBsrv: DBSRV_1 IP: 1.2.3.4 Current: 1
App: App_1 PID: 23996
App: App_1 PID: 23996 DBsrv: DBSRV_1 IP: 1.2.3.1 Current: 10
App: App_1 PID: 23996 DBsrv: DBSRV_5 IP: 1.2.3.5 Current: 12

答案 2 :(得分:0)

awk '$2 $4 != last { if(NR > 1) { print "--" }; print $1 $2 $3 $4; last = $2 $4; firs }
     { print }' < text1.txt

答案 3 :(得分:0)

for ID in `cat Text1.txt | awk '{print $4}' | sort -u`
do 
    cat Text1.txt | grep "$ID" | awk '{print $1" "$2" "$3" "$4}' | head -n 1
    cat Text1.txt | grep "$ID"
    echo '--'
done

答案 4 :(得分:0)

带注释的awk解决方案:

awk '{
 if (prevPid != $4) {  # New group starting? (new PID?)
     # Output group header, prefixed by "--" line, unless this is the 1st line.
   print (NR > 1 ? "--\n" : "") $1, $2, $3, $4
     # Save PID for next iteration.
   prevPid=$4
 }
 print  # (Also) print each input line as is.
}' file

答案 5 :(得分:0)

这可能适合你(GNU sed):

sed -re '1{:a;h;G;s/ DBsrv[^\n]*//;t};G;/(PID: [0-9]+ ).*\n.*\1/{P;d};i\--' -e 's/\n.*//;ta' file

这使用保留空间来保存每个pid更改并将其与后续行进行比较。