【问题标题】:How Do I Pull Info from String如何从字符串中提取信息
【发布时间】:2010-04-24 23:38:31
【问题描述】:

我正在尝试从使用 bash 运行的负载中提取动态。我已经到了获得我想要的字符串的地步,现在我想从中提取某些可能会有所不同的信息。返回的字符串如下:

Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0

每个数字的长度都可以并且会有所不同,但整体结构将保持不变。我想要做的是能够获取这些数字并将它们加载到一些 bash 变量中,即:

RECORDS=??
DELETED=??
SKIPPED=??
WARNING=??

在正则表达式中我会这样做:

Records: (\d*?) Deleted: (\d*?) Skipped (\d*?) Warnings (\d*?)

并在我的变量中使用 4 个组。

【问题讨论】:

  • 那个问题是指根据分隔符拆分字符串,我只想拉数字,我没有共同的分隔符。
  • 事实上,项目之间的空间看起来像是一个合适的分隔符。请参阅答案中脚本的剪切版本。

标签: regex bash string string-parsing


【解决方案1】:

您可以在 Bash >= 3.2 版本中使用正则表达式匹配:

[[ $line =~ ([[:digit:]]+).*([[:digit:]]+).*([[:digit:]]+).*([[:digit:]]+) ]]

RECORDS=${BASH_REMATCH[1]}
DELETED=${BASH_REMATCH[2]}
SKIPPED=${BASH_REMATCH[3]}
WARNING=${BASH_REMATCH[4]}

【讨论】:

  • 很好的答案。即使我写了另一个答案,我也会选择你。这是我不知道的 bash 的一些功能。
  • @rmarimon,这行得通,但只有当您的线路与每次显示的完全相同时。如果有更多数据,它将无法正常工作。
【解决方案2】:

内置的read 命令可以解决问题:

read TMP1 RECORDS TMP2 DELETED TMP3 SKIPPED TMP4 WARNING

更新:你也可以使用set

set $line
RECORDS=$2
DELETED=$4
SKIPPED=$6
WARNING=$8

【讨论】:

  • 读取是为了捕捉用户输入,我没有手动输入,该字符串被设置为一个名为$r的变量
  • @Russ:read 可以从标准输入中获取值:s="foo bar baz"; read a b c <<< $s
【解决方案3】:

这是一个您可以使用的 shell 函数,它只创建多个名称/值对。它假定事物的格式如您所说,但很容易更改:

parseline() {
    while [ $# -ge 2 ] ; do
        eval $(echo $1 | tr -d : | tr '[a-z]' '[A-Z]')="$2"
        shift 2
    done
}

像这样执行它:

$ parseline Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0
$ echo $RECORDS
2910
$ echo $WARNINGS
0

【讨论】:

    【解决方案4】:

    您可以根据行的结构尝试使用“sed”或“cut”,如下所示:

    #!/bin/sh                                                                       
    
    DYNAMIC="Records: 2910 Deleted: 1 Skipped: 2 Warnings: 3"
    
    RECORDS=`echo "$DYNAMIC" | sed 's/.*Records: \([0-9]*\).*/\1/g'`
    DELETED=`echo "$DYNAMIC" | sed 's/.*Deleted: \([0-9]*\).*/\1/g'`
    SKIPPED=`echo "$DYNAMIC" | sed 's/.*Skipped: \([0-9]*\).*/\1/g'`
    WARNINGS=`echo "$DYNAMIC" | sed 's/.*Warnings: \([0-9]*\).*/\1/g'`
    
    echo "Records $RECORDS"
    echo "Deleted $DELETED"
    echo "Skipped $SKIPPED"
    echo "Warnings $WARNINGS"
    
    echo "$DYNAMIC" | cut -d " " -f2
    echo "$DYNAMIC" | cut -d " " -f4
    echo "$DYNAMIC" | cut -d " " -f6
    echo "$DYNAMIC" | cut -d " " -f8
    

    【讨论】:

    • 太复杂了,我更喜欢Bolo的方案。
    【解决方案5】:
    #!/bin/bash
    s="Records: 2910 Deleted: 0 Skipped: 0 Warnings: 0"
    s=${s//: /=}
    for i in $(printf ${s// /"\n"})
    do
     eval $i
    done
    
    echo "Records: $Records"
    echo "Deleted: $Deleted"
    echo "Skipped: $Skipped"
    echo "Warnings: $Warnings"
    

    输出

    $ ./shell.sh
    Records: 2910
    Deleted: 0
    Skipped: 0
    Warnings: 0
    

    【讨论】:

      猜你喜欢
      • 2015-01-25
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      相关资源
      最近更新 更多