【问题标题】:bash sort and format text outputbash 排序和格式化文本输出
【发布时间】:2014-06-07 06:18:09
【问题描述】:

我是 bash 脚本的新手,

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

文本 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

【问题讨论】:

  • 与具有相同 PID 的同一个应用程序的连接是否总是分组在一起,就像在您的示例数据中一样?你说的是“总连接数”。分组是否足够,还是需要sum连接数?
  • 嗨,不,连接已经分组,我需要按应用程序名称和 PID 分组

标签: bash sorting awk sed


【解决方案1】:
awk '$2 $4 != last { if(NR > 1) { print "--" }; print $1 $2 $3 $4; last = $2 $4; firs }
     { print }' < text1.txt

【讨论】:

  • 很有希望,但您尝试在单引号内使用单引号,您有一个孤立的 firs,并且您的组标头缺少字段之间的分隔符。
【解决方案2】:
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

【讨论】:

  • Don't read lines with for,拜托。顺便说一句,cat 也无用。更不用说效率很低的方法了。
  • 然而,它运行良好,它输出了我需要的东西,谢谢@damgad
  • @MarcosPousada 这里有很多好的答案,你选择了最差的一个!
  • 呵呵,不,我正在测试他们每个人..这是我能做的至少...@gniourf_gniourf
【解决方案3】:

你可以这样做:

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

【讨论】:

  • 谢谢哥们,太棒了,它打印出我想要的!
【解决方案4】:

你可以使用这个 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

【讨论】:

    【解决方案5】:

    带注释的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
    

    【讨论】:

      【解决方案6】:

      这可能对你有用(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 更改并将其与后续行进行比较。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        • 2017-11-01
        • 2014-05-20
        相关资源
        最近更新 更多