【问题标题】:UNIX (AIX) Command Help - Sed & AwkUNIX (AIX) 命令帮助 - Sed 和 Awk
【发布时间】:2015-11-04 23:01:14
【问题描述】:

我在 AIX 6.1 上运行它。

此命令的预期目的是以下列格式显示以下信息:

GetUsedRAM:GetUsedSwap:CPU_0_System:CPU_0_User:…CPU_N_System:CPU_N_User

该命令由几个子命令组成:

echo `vmstat 1 2 | tr -s ' ' ':' | cut -d':' -f4,5,14-15 | tail -1 | sed 's/\([0-9]*:[0-9]*:\)\([0-9]*:[0-9]*\)/\1/'``mpstat -a 1 1 | tr -s ' ' '|' | head -8 | tail -4 | cut -d'|' -f 25,27 | awk -F "|" '{printf "%.0f:%.0f:",$2,$1}' | sed '$s/.$//'| sed -e "s/ \{1,\}$//"| awk '{int a[10];split($1, a,":");printf("%d:%d:%d:%d:%d:%d:%d:%d",a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7])}'`

为了清楚起见,我将重新格式化:

echo \
`vmstat 1 2 |
    tr -s ' ' ':' |
    cut -d':' -f4,5,14-15 |
    tail -1 |
    sed 's/\([0-9]*:[0-9]*:\)\([0-9]*:[0-9]*\)/\1/' \
` \
`mpstat -a 1 1 |
    tr -s ' ' '|' |
    head -8 |
    tail -4 |
    cut -d'|' -f 25,27 |
    awk -F "|" '{printf "%.0f:%.0f:",$2,$1}' |
    sed '$s/.$//' |
    sed -e "s/ \{1,\}$//" |
    awk '{int a[10];split($1, a,":");printf("%d:%d:%d:%d:%d:%d:%d:%d",a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7])}' \
`

我了解所有 trcuthead tail 和(大致) vmstat/mpstat 命令。第一个 sed 是我迷路的地方,我尝试在较小的部分中运行命令,但不太确定为什么它似乎可以作为一个整体工作,但在下一个 之前截断命令时却不行>tr

我对 awk 命令也不太确定,尽管我模糊地理解了这个前提,因为它是一个允许格式化输出的函数。

同样,我对 sed 是一个允许在某些文件中替换某些字符串/字符的命令有模糊的理解。

我无法弄清楚上述案例中的具体实现是什么。

任何人都可以就整个命令上下文中的每个 sedawk 步骤的确切情况提供一些清晰或方​​向吗?

感谢您的帮助。

【问题讨论】:

  • 第一个sed 命令末尾的``mpstat -a 1 1 部分没有意义,我很惊讶它没有给你语法错误——它打算做什么?哦,等等——你没有正确地扩展你的单线。我会编辑它来为你解决这个问题。
  • 好的,我已经这样做了,但是现在 - 最后一个 awk 命令一定会给你一个语法错误,对吧?声明 int a[10] 似乎试图声明一个大小为 10 的数组 a 包含整数,但您没有声明 awk 变量,而单词 int 是 awk 函数的名称,而不是类型(所有 awk标量变量属于“数字字符串”类型)。老实说,整个命令行是一团糟,应该放弃,而使用单个 awk 命令 - 如果您向我们展示示例输入(vmstat 和 mpstat 命令的输出)以及相关的所需输出,我们可以为您提供帮助。跨度>
  • 您需要缩小问题的范围,或者使其更精确。如果您想知道 sed 's/\([0-9]*:[0-9]*:\)\([0-9]*:[0-9]*\)/\1/ 做了什么,那么您应该问一下。
  • man sed ; man awk 怎么样?或者——更好的是——从网上阅读文档。
  • @EdMorton 感谢您的编辑。预期目的是以固定格式显示 Ram 使用情况、Swap 使用情况和 Cpu 使用情况信息。该格式是该问题第三行显示的格式。例如。 542067:173374:0:0:35:0:0:0:0:0 是我从完整命令中得到的输出。将命令作为一个整体运行不会产生语法错误,但在某些部分会产生。我同意该声明是一团糟,但这是我得到的。

标签: unix awk sed command aix


【解决方案1】:

简化

这两个更简单的命令将得到完全相同的输出:

# GetUsedRAM:GetUsedSwap:CPU_0_System:CPU_0_User:…CPU_N_System:CPU_N_User

# Select fields 4,5 of last line, and format with :
comm1=`vmstat 1 2 |
        awk '$4~/[0-9]/{avm=$4;fre=$5} END{printf "%s:%s",avm,fre}'
       `
# Select fields 27 (sy) and 25 (us) for four cpu, print as decimal.
comm2=`mpstat -A 1 1 |
        awk -v firstline=6 -v cpus=4 '
             BEGIN{start=firstline-1; end=firstline+cpus;}
             NR>start && NR<end   {printf( ":%d:%d", $27,$25)}'
       `

echo "${comm1}${comm2}"

说明。

原始命令说明

整个命令是两个命令的串联。

  1. 第一条命令:

output of the vmstat is shown in this link.
第 4 列和第 5 列是“avm”和“fre”。第 14 和 15 列的输出, 似乎是“我们”(用户)和“sy”(系统)。我说似乎没有输出 来自用户的确认。

The first command
`vmstat 1 2 |               # Execute the command vmstat.
    tr -s ' ' ':' |         # convert all spaces to colon (:).
    cut -d':' -f4,5,14-15 | # select fields 4,5,14,and 15
    tail -1 |               # select last line.
    sed 's/\([0-9]*:[0-9]*:\)\([0-9]*:[0-9]*\)/\1/' \ # See below.
`

sed 命令在大括号内选择冒号前的所有数字 [0-9]* 重复了两次。然后再一次(没有最后一个冒号)。这就是全部 字符串分为两部分:« (dd:dd:)(dd:dd) »(d 表示数字)。
最后,它将整个字符串替换为内部选择的内容 第一个大括号/\1/.
所有这些复杂性只是删除了 cut 选择的字段 14 和 15。

具有完全相同输出的更简单的命令是:

Select fields 4,5 of last line, and format with (:).
`vmstat 1 2 | awk '
     $4~/[0-9]/{avm=$4;fre=$5} END{printf "%s:%s:",avm,fre}'
`
  1. 第二条命令:

mpstat -A 的输出类似于this one from Linux
也类似于这个AIX mpstat -d output

但是,计算机上 mpstat -a (ALL) 的 AIX 6.1 的确切输出 used 可能有几种变化。无论如何,以预期的决赛为指导 所需输出:CPU_0_System:CPU_0_User:…CPU_N_System:CPU_N_User。

看来要选择的列应该是us(用户)和sy (sys) 使用 cpu 的所有 cpu 使用时间百分比, 在计算机上测量的似乎是四个。

manual for AIX 6.1 mpstat is here

它有一个列表,其中包含选项时显示的所有 40 列 -a ALL 被使用:

CPU min maj mpcs mpcr dev soft dec ph cs ics bound rq push
S3pull S3grd S0rd S1rd S2rd S3rd S4rd S5rd S3hrd S4hrd S5hrd
sysc us sy wa id pc %ec ilcs vlcs lcs %idon %bdon %istol %bstol %nsp

us 和 sy 被列为字段 27 和 28,但是显示的命令 由用户选择字段编号 25 和 27。关闭但不一样。这 确认的唯一方法是接收用户的命令输出。

为了测试,我将使用output of mpstat 5 1 from here

# mpstat 5 1

System configuration: lcpu=4 ent=1.0 mode=Uncapped

cpu   min  maj  mpc  int   cs  ics   rq  mig lpa   sysc us sy wt id   pc  %ec  lcs
0 4940    0    1  632  685  268    0  320 100 263924 42 55  0  4 0.57 35.1  277
1  990    0    3 1387 2234  805    0  684 100 130290 28 47  0 25 0.27 16.6  649
2 3943    0    2  531  663  223    0  389 100 276520 44 54  0  3 0.57 34.9  270
3 1298    0    2 1856 2742  846    0  752 100  82141 31 40  0 29 0.22 13.4  650

ALL 11171    0    8 4406 6324 2142    0 2145 100 752875 39 51  0 10 1.63 163.1 1846


The second command
`mpstat -A 1 1 |            # execute command
    tr -s ' ' '|' |         # replace all spaces with (|).
    head -8 |               # select 8 first lines.
    tail -4 |               # select last four lines.
    cut -d'|' -f 25,27 |    # select fields 25 and 27
    awk -F "|" '{printf "%.0f:%.0f:",$2,$1}' |  # print the fields as integers.
    sed '$s/.$//' |             # on the last line ($), substitute the last character (.$) by nothing.
    sed -e "s/ \{1,\}$//" |     # remove trailing space(s).
    awk '{
        int a[10];
        split($1, a,":");
        printf("%d:%d:%d:%d:%d:%d:%d:%d",a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7])
    }' \
`

关于 int:对于旧版本的 awk,调用不带括号的函数相当于在 $0 上调用函数。 int 等价于 int($0),既不打印也不使用。 a[10] 的值也是如此。

拆分将命令的每个值设置在 a[i] 中。然后,a[i] 的所有值都打印为小数。

等效且更简单的方法是:

Command #2
`mpstat -A 1 1 |
 awk -v firstline=6 -v cpus=4 '
        BEGIN{start=firstline-1; end=firstline+cpus;}
        NR>start && NR<end   {printf( ":%d:%d", $27,$25)}'
`

【讨论】:

    猜你喜欢
    • 2018-04-04
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    • 2015-04-12
    • 2014-09-19
    • 1970-01-01
    相关资源
    最近更新 更多