正确的工具,用于从blkid程序的输出中过滤UUID(使用grep,cut或awk,e.t.c)

时间:2012-11-26 13:17:05

标签: sed awk grep

我想过滤blkid的输出以获取UUID。

blkid的输出看起来像

案例1:

$ blkid
/dev/sda2: LABEL="A" UUID="4CC9-0015"
/dev/sda3: LABEL="B" UUID="70CF-169F"
/dev/sda1: LABEL=" NTFS_partition" UUID="3830C24D30C21234"

在某些情况下,blkid的输出看起来像

案例2: -

$ blkid
/dev/sda1: UUID="d7ec380e-2521-4fe5-bd8e-b7c02ce41601" TYPE="ext4" 
/dev/sda2: UUID="fc54f19a-8ec7-418b-8eca-fbc1af34e57f" TYPE="ext4" 
/dev/sda3: UUID="6f218da5-3ba3-4647-a44d-a7be19a64e7a" TYPE="swap" 

我想过滤掉UUID。

使用 grep 剪切的组合,可以将其作为

/sbin/blkid | /bin/grep 'sda1' | /bin/grep -o -E 'UUID="[a-zA-Z|0-9|\-]*' | /bin/cut -c 7-

我尝试使用 awk grep 剪切,如下所示,以过滤UUID

$ /sbin/blkid | /bin/grep 'sda1' | /usr/bin/awk '{print $2}' | /bin/sed 's/\"//g' | cut -c 7-
7ec380e-2521-4fe5-bd8e-b7c02ce41601

上述命令(使用awk)不可靠,因为有时在 blkid 程序的输出中可能会出现一些额外的字段,例如LABEL,如上面的输出所示。

使用可靠运行的 awk 创建命令的最佳方法是什么? 如果任何其他优雅的方法使用bin和core utils退出作业,请发布。我不想使用perl或python,因为这必须在busybox上运行。

注意: - 我正在使用 busybox blkid / dev / sda1 无法作为args传递(我正在使用的版本不支持它)因此过滤线的grep。

更新: - 添加了CASE 2:-output以显示无法依赖字段位置。

6 个答案:

答案 0 :(得分:53)

为什么你这么复杂?

试试这个:

# blkid -s UUID -o value
d7ec380e-2521-4fe5-bd8e-b7c02ce41601
fc54f19a-8ec7-418b-8eca-fbc1af34e57f
6f218da5-3ba3-4647-a44d-a7be19a64e7a

或者这个:

# blkid -s UUID -o value /dev/sda1
d7ec380e-2521-4fe5-bd8e-b7c02ce41601

如果没有,请安装正确的blkid软件包:

sudo apt-get install util-linux
sudo yum install util-linux

答案 1 :(得分:5)

对于所有UUID,你可以这样做:

$ blkid | sed -n 's/.*UUID=\"\([^\"]*\)\".*/\1/p' 
d7ec380e-2521-4fe5-bd8e-b7c02ce41601
fc54f19a-8ec7-418b-8eca-fbc1af34e57f
6f218da5-3ba3-4647-a44d-a7be19a64e7a

说,仅针对特定的sda1:

$ blkid | sed -n '/sda1/s/.*UUID=\"\([^\"]*\)\".*/\1/p' 
d7ec380e-2521-4fe5-bd8e-b7c02ce41601

sed命令尝试对UUID关键字后双引号内的内容进行分组,并用令牌替换整行。

答案 2 :(得分:2)

这是一个简短的awk解决方案:

blkid | awk 'BEGIN{FS="[=\"]"} {print $(NF-1)}'

<强>输出:

4CC9-0015
70CF-169F
3830C24D30C21234

<强>解释

  • BEGIN{FS="[=\"]"}:使用="作为分隔符
  • {print $(NF-1)}NF代表字段数;这里我们打印第二个到最后一个字段
  • 这是基于blkid输出的一致结构:引号中的UUID位于每行的末尾。

<强>可替换地:

blkid | awk 'BEGIN{FS="="} {print $NF}' | sed 's/"//g'

答案 3 :(得分:0)

data.txt中

/dev/sda2: LABEL="A" UUID="4CC9-0015"
/dev/sda3: LABEL="B" UUID="70CF-169F"
/dev/sda1: LABEL=" NTFS_partition" UUID="3830C24D30C21234"

awksed组合

cat data.txt | awk 'BEGIN{FS="UUID";RS="\n"} {print $2}' | sed -e 's/=//'  -e 's/"//g'

说明:

  1. 将字段分隔符设置为字符串'UUID',$2将提供其余输出
  2. 然后使用sed删除=",如-e所示为开关,以便您可以在一个中提供多个sed命令/表达式。
  3. 使用结尾"选项(即全局)删除所有g个字词。

答案 4 :(得分:0)

该问题带有一个“ e.t.c”,因此我将假定python是其中的一种;)

#!/usr/bin/env python3

import subprocess, re, json

# get blkid output
blkid = subprocess.check_output(["blkid"]).decode('utf-8')


devices = []
for line in [x for x in blkid.split('\n') if x]:
        parameters = line.split()
        for idx, parameter in enumerate(parameters):
                if idx is 0:
                        devices.append({"DEVICE": re.sub(r':$','',parameter)})
                        continue

                key_and_value = parameter.split('=')
                devices[-1].update({
                        key_and_value[0]: re.sub(r'"','',key_and_value[1])
                })


uuids = [{dev['DEVICE']: dev['UUID']} for dev in devices if 'UUID' in dev.keys()]
print(json.dumps(uuids, indent=4, sort_keys=True))

尽管如此,这可能是矫kill过正,此脚本XD中缺少许多错误处理/优化功能

答案 5 :(得分:0)

我假设您正在 initramfs 中使用 busybox 并且您正在等待您的 e.g.带有 rootfs 的 USB 驱动器可用。

您可以使用以下 awk 脚本(兼容busybox awk)。

# cat get-ruuid.awk 
BEGIN {
  ruuid=ENVIRON["RUUID"]
}

/^\/dev\/sd[a-z]/ {
  if (index($0, tolower(ruuid)) || index($0, toupper(ruuid))) {
    split($1, parts, ":")
    printf("%s\n", parts[1])
    exit(0) # Return success and stop further scanning.
  }
}

END {
  exit(1) # If we reach the end, it means RUUID was not found.
}

从例如以下调用它初始化脚本;这不是最理想的方式。

# The UUID of your root partition
export RUUID="<put proper uuid value here>"

for x in 1, 2, 3, 4, 5 ; do
  mdev -s
  found=$(blkid | awk -f ./get-ruuid.awk)
  test -z $found || break; # If no longer zero length, break the loop.
  sleep 1
done

但如果这是您想要 initramfs 的唯一原因,我将使用“root=PARTUUID=... waitroot”Linux 内核命令行选项。检查内核文档和来源。

使用 blkid 命令获取根分区的正确 PARTUUID(不是 UUID)。