特定文本的bash过滤器/条带输出

特定文本的bash过滤器/条带输出,bash,sed,awk,Bash,Sed,Awk,给定dmesg日志输出,特别是其中的一行,例如: NET: Registered protocol family 10 在脚本中,我希望有一个已定义的变量,如$net\u version,该变量将检查我是否使用值10来定义它,如果它与在dmesg中找到的值匹配 我查看了sed和awk,但是对于awk,我找不到正确的方法剥离输出,使变量与dmesg行中的最后一个字匹配 我认为这是一个简单的问题,但是我在确定正确的方法时遇到了一个问题。您可以使用sed打印匹配行: var=10 sed -n "/

给定dmesg日志输出,特别是其中的一行,例如:

NET: Registered protocol family 10
在脚本中,我希望有一个已定义的变量,如
$net\u version
,该变量将检查我是否使用值10来定义它,如果它与在dmesg中找到的值匹配

我查看了sed和awk,但是对于awk,我找不到正确的方法剥离输出,使变量与dmesg行中的最后一个字匹配


我认为这是一个简单的问题,但是我在确定正确的方法时遇到了一个问题。

您可以使用
sed
打印匹配行:

var=10
sed -n "/NET: Registered protocol family $var/p" file
  • -n
    避免打印所有行
  • “/NET:..$var/p”
    用户使用双引号展开变量
  • /p
    打印匹配的行
或者当然
grep

$ grep "NET: Registered protocol family $var" file
$ var=10
$ grep "NET: Registered protocol family $var" a
NET: Registered protocol family 10
例子 使用
grep

$ grep "NET: Registered protocol family $var" file
$ var=10
$ grep "NET: Registered protocol family $var" a
NET: Registered protocol family 10

我建议不要使用未编排的正则表达式。如果“NET:Registered protocol family 100”不应该匹配,那么这里的一些其他答案可能会给出误报

在下面的
grep
解决方案中,注意正则表达式末尾的锚点。此外,grep的
-q
选项使其“安静”,因此它可以简单地用于通知您的
if

#!/bin/sh

val="10"

if dmesg | grep -q "^NET: Registered protocol family ${val}$"; then
  echo "matched"
fi
或者,您可以使用awk,但您需要两个条件——一个匹配行上的字符串,另一个匹配变量

awk -v val="10" '/^NET: Registered protocol family / && $NF==val { print "matched" }'
或者,您也可以使用单个字符串匹配:

awk -v val="10" '$0 == "NET: Registered protocol family "val { print "matched" }'
或者,如果要使用
sed
在shell脚本中剥离输出以进行求值,可以这样做:

#!/bin/bash

val=$(dmesg | sed -ne '/^NET: Registered protocol family /{;s///p;q}')

if [ "$val" -eq "10" ]; then
  echo "matched"
fi
这里的sed脚本看起来有点复杂,所以让我们把它分解出来

  • -n
    选项告诉它默认情况下不打印输出
  • 我们首先搜索包含NET:text的行,如果找到,
    • 我们用我们找到的文本替换为“无”(因此将其剥离)
    • 命令末尾的
      p
      告诉它,如果替换成功,则打印输出,并且
    • 我们退出,从而保护自己不受字符串多次出现的影响
如果您希望能够处理dmesg文件中的多个事件,则可能需要通过循环运行:

#!/bin/sh

dmesg \
 | sed -ne '/^NET: Registered protocol family /{;s///p;q}') \
 | while read val; do

     if [ "$val" -eq "10" ]; then
       echo "matched"
     fi

   done

为了便于阅读,我将dmesg管道拆分为多行,但您可以将其全部编入脚本中。

需要做类似的事情,但要查找USB闪存驱动器信息。我从命令开始:

    dmesg | grep -i 'scsi' | grep -i removable
我得到以下两个结果:

    [    3.197914] sd 2:0:0:0: [sdc] Attached SCSI removable disk
    [22373.515566] sd 3:0:0:0: [sdd] Attached SCSI removable disk
然后我需要循环获取sdc和sdd值,并插入var$SDDRV以运行下一个cmd:

    fdisk -l | grep -i disk | grep ${SDDRV}
如果磁盘未实际连接(本例为sdc),则fdisk cmd不会产生任何结果,但由于在本例中sdd处于活动状态,因此结果为:

    Disk /dev/sdd: 63.2 GB, 63216549888 bytes
然后我需要解析出闪存驱动器的大小,它是63.2GB(我的64GB闪存),因为大小大于63GB,所以将var SDNAM设置为“64Gig”(闪存的名称)。我有1GB、2GB、16GB和64GB,因此必须有逻辑为任何/所有插入的驱动器获取正确的名称,正如您所看到的,linux看到的大小不等于mfg大小标签。不知道为什么,但仍然需要为每个插入的设备获取正确的名称。 接下来,我需要运行以下命令:

    df -h | grep ${SDDRV}
结果,我显示了来自“df”的列标签:

    Filesystem      Size  Used Avail Use% Mounted on
    /dev/sdd1        59G   11M   59G   1% /media/ndavis/USB DISK
因此,我必须解析“可用空间”和“装载点”

如果我处理好了所有这些,那么我应该:

  • 驱动器名
  • 驱动器大小
  • 可用空间
  • 挂载点

  • 然后,我用所有这些创建了一个VAR,并将其导出,以便其他需要USB闪存驱动器信息的脚本可以使用。

    非常感谢你们两位,这些解释真的很有帮助!