【问题标题】:Bash Text ParsingBash 文本解析
【发布时间】:2018-02-27 17:14:41
【问题描述】:

我对参数替换感到困惑。基本上要解析的文件结构如下:

foo.txt:
    system.switch_cpus.commit.op_class_0::total     10000000                       # Class of committed instruction
    system.switch_cpus.commit.bw_lim_events      10000000                       # number cycles where commit BW limit reached
    system.switch_cpus.rob.rob_reads             80558432                       # The number of ROB reads
    system.switch_cpus.rob.rob_writes            43430539                       # The number of ROB writes
    system.switch_cpus.timesIdled                   37218                       # Number of times that the entire CPU went into an idle state and unscheduled itself
    system.switch_cpus.idleCycles                 2755508                       # Total number of cycles that the CPU has spent unscheduled due to idling
    system.switch_cpus.committedInsts            10000000                       # Number of Instructions Simulated
    system.switch_cpus.committedOps              10000000                       # Number of Ops (including micro ops) Simulated
    system.switch_cpus.cpi                       8.369191                       # CPI: Cycles Per Instruction
    system.switch_cpus.cpi_total                 8.369191                       # CPI: Total CPI of All Threads
    system.switch_cpus.ipc                       0.119486                       # IPC: Instructions Per Cycle
    system.switch_cpus.ipc_total                 0.119486                       # IPC: Total IPC of All Threads
    system.switch_cpus.int_regfile_reads         21773538                       # number of integer regfile reads
    system.switch_cpus.int_regfile_writes         9447282                       # number of integer regfile writes

我想找到以下变量并打印出对应的值:

    list=(IPC CPI)
IPC="system.switch_cpus.ipc"
CPI="system.switch_cpus.cpi"

for i in $list:
do 
awk -v a="$i" '{$1 == $a} {print}' $1
done

然后我使用以下命令运行脚本:

./parser.sh foo.txt

这是打印整个文件。

Output:
system.switch_cpus.commit.op_class_0::total     10000000                       # Class of committed instruction
system.switch_cpus.commit.bw_lim_events      10000000                       # number cycles where commit BW limit reached
system.switch_cpus.rob.rob_reads             80558432                       # The number of ROB reads
system.switch_cpus.rob.rob_writes            43430539                       # The number of ROB writes
system.switch_cpus.timesIdled                   37218                       # Number of times that the entire CPU went into an idle state and unscheduled itself
system.switch_cpus.idleCycles                 2755508                       # Total number of cycles that the CPU has spent unscheduled due to idling
system.switch_cpus.committedInsts            10000000                       # Number of Instructions Simulated
system.switch_cpus.committedOps              10000000                       # Number of Ops (including micro ops) Simulated
system.switch_cpus.cpi                       8.369191                       # CPI: Cycles Per Instruction
system.switch_cpus.cpi_total                 8.369191                       # CPI: Total CPI of All Threads
system.switch_cpus.ipc                       0.119486                       # IPC: Instructions Per Cycle
system.switch_cpus.ipc_total                 0.119486                       # IPC: Total IPC of All Threads
system.switch_cpus.int_regfile_reads         21773538                       # number of integer regfile reads
system.switch_cpus.int_regfile_writes         9447282                       # number of integer regfile writes

如何在 shell 中创建具有自己值的变量列表,并使用 awk 或 sed 从文件中解析每个变量?

【问题讨论】:

  • i=cpi 时的预期输出是什么?
  • 也许一个简单的 egrep 就可以了? egrep -iw 'system.switch_cpus.ipc|system.switch_cpus.cpi' foo.txt
  • 预期输出是包含“foo.txt”中 cpi 值的整行或第二个变量。我想我以后可以在 teh awk 中更改该设置。
  • @ViniciusPlacco:不幸的是,我的变量列表越来越多。在这个特定的问题中,我只展示了 2 个变量。 egrep 选项很酷,但是当搜索 10 个变量时,它可能会变得棘手且容易出错:-(
  • 好的,我明白了!您可能会从这篇文章中获得有关grep的一些信息:stackoverflow.com/questions/17863301/…。祝你好运!

标签: bash shell awk


【解决方案1】:

您可以在一个 awk 脚本中完成所有操作,如果您的列表不在文件中,您可以使用此处的文档和文件替换,如下所示。

$ awk 'NR==FNR{a[$1]; next} $1 in a' <(cat << EOF
system.switch_cpus.ipc
system.switch_cpus.cpi
EOF
) file

会给你

system.switch_cpus.cpi                       8.369191                       # CPI: Cycles Per Instruction
system.switch_cpus.ipc                       0.119486                       # IPC: Instructions Per Cycle

如果你想用一个变量一次搜索一个

$ var='system.switch_cpus.ipc'; awk -v var="$var" '$1==var' file

system.switch_cpus.ipc                       0.119486                       # IPC: Instructions Per Cycle

但是,在这种情况下,使用 grep 可能会更好

$ var='system.switch_cpus.ipc'; grep -wF "$var" file

system.switch_cpus.ipc                       0.119486                       # IPC: Instructions Per Cycle

更新

如果你的变量名在一个列表中,你可以用这个解码值

$ vars=(var1 var2)        # define the list with variables, values even may not be assigned yet
$ var1=value1; var2=value2                   # assign values
$ for v in ${vars[@]}; do echo ${!v}; done   # extract values with indirect reference
value1
value2

【讨论】:

  • 我需要使用 for 循环运行,因为我有大约 15 个变量要在文件中查找。文件选项可能有效。但是我在 shell 中没有替代参数的选项(就像列表元素“IPC”具有 awk 应该找到的值“system.switch_cpus.ipc”)?基本上我想看看shell中是否有两个时间参数替换选项。但是,你的选择也对我有用。谢谢。
  • 谢谢@karakfa。我正在寻找变量间接。我刚刚做了,现在它可以按我的意愿工作了。
【解决方案2】:

此代码将打印整条记录

awk -v a="$i" '{ if($1 == a){print $0} }' $1

您的代码的一个问题是变量 a 在 awk 中不能在 $ 前面。

【讨论】:

  • awk -v a="$i" '$1==a' $1 会做同样的事情,而且更惯用。
  • 嗯,它的可读性较差。不是每个人都像你一样了解 awk ;-)
猜你喜欢
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 2020-02-09
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多