使用 grep 搜索整个 word/phrase 只有部分
Using grep to search for a whole word/phrase with only part
我正在尝试使用终端命令 $ diskutil info "BOOTCAMP" | grep "Node"
为我的 MacBook Pro 上的 Bootcamp 分区获取当前 "Device Node"(例如 disk0s4)。这很好用。我想创建一个程序来对 partition/volume 做一些事情,因为它可能会改变节点(因为我搞砸了我的文件系统)。
因此我需要创建一个变量或存储设备节点(并且只有设备节点)的值,以便以后使用它。这是我试过的。
$ grepVar=$(diskutil info "BOOTCAMP" | grep "Node")
$ A="$(cut -d'/' -f1 <<<"$grepVar")"
$ echo "$A hi"
Device Node: hi
当我 运行 diskutil info "BOOTCAMP" | grep "Node"
:
时,实际文件是这样读的
Device Node: /dev/disk0s4
很明显cut
把错误的部分删掉了,保留了间距。我尝试了一些其他技术,但没有成功。有人会推荐什么? -o 方法只给了我 /dev/disk0s4
的一部分,而不是整个 phrase/word。我是否只需要在 "grepping" 之后添加它?怎么样?
非常感谢
在 macOS 中,您可以使用 pcregrep
,例如,仅获取 disk0s4
:
echo "Device Node: /dev/disk0s4" | pcregrep -o "/dev/\K.*"
会return:
disk0s4
选项-o
用于仅显示与模式匹配的行的一部分而不是整行。
\K
可以理解为排除了它前面左边的所有内容,return 只排除了右边的部分。
请记住 grep
是首字母缩写词。全局正则表达式打印——就像您可能在 vi
中使用的命令一样,列出与正则表达式匹配的行。 PCRE 等额外功能不可移植,可能无法在所有系统中使用——甚至在您未安装软件的情况下也不可用。
通常 sed
提供了操作文本流的最快或最简洁的方法。例如:
diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p'
这会找到您正在查看的文本行,去掉最后一个斜线之前的所有内容,然后打印该行的剩余部分。将其放入变量中非常简单:
node=$(diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p')
或
read -r node < <(diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p')
您可以像这样交替处理 awk
中的输出:
diskutil info "BOOTCAMP" | awk -F/ '/Device Node:/ { print $NF }'
这再次找到您感兴趣的行,并打印最后一个字段 .. 字段分隔符设置为正斜杠。
如果您真的只想为此使用 grep
,您可以进行一些管道安装:
diskutil info "BOOTCAMP" | grep 'Device Node:' | grep -o '/[^/]*$' | grep -Eo '[^/]+'
当然,如果您愿意,可以将最后的 grep
替换为 cut -d/ -f2
。
当然,如果 BOOTCAMP
不存在,所有这些都会失败。
我正在尝试使用终端命令 $ diskutil info "BOOTCAMP" | grep "Node"
为我的 MacBook Pro 上的 Bootcamp 分区获取当前 "Device Node"(例如 disk0s4)。这很好用。我想创建一个程序来对 partition/volume 做一些事情,因为它可能会改变节点(因为我搞砸了我的文件系统)。
因此我需要创建一个变量或存储设备节点(并且只有设备节点)的值,以便以后使用它。这是我试过的。
$ grepVar=$(diskutil info "BOOTCAMP" | grep "Node")
$ A="$(cut -d'/' -f1 <<<"$grepVar")"
$ echo "$A hi"
Device Node: hi
当我 运行 diskutil info "BOOTCAMP" | grep "Node"
:
Device Node: /dev/disk0s4
很明显cut
把错误的部分删掉了,保留了间距。我尝试了一些其他技术,但没有成功。有人会推荐什么? -o 方法只给了我 /dev/disk0s4
的一部分,而不是整个 phrase/word。我是否只需要在 "grepping" 之后添加它?怎么样?
非常感谢
在 macOS 中,您可以使用 pcregrep
,例如,仅获取 disk0s4
:
echo "Device Node: /dev/disk0s4" | pcregrep -o "/dev/\K.*"
会return:
disk0s4
选项-o
用于仅显示与模式匹配的行的一部分而不是整行。
\K
可以理解为排除了它前面左边的所有内容,return 只排除了右边的部分。
请记住 grep
是首字母缩写词。全局正则表达式打印——就像您可能在 vi
中使用的命令一样,列出与正则表达式匹配的行。 PCRE 等额外功能不可移植,可能无法在所有系统中使用——甚至在您未安装软件的情况下也不可用。
通常 sed
提供了操作文本流的最快或最简洁的方法。例如:
diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p'
这会找到您正在查看的文本行,去掉最后一个斜线之前的所有内容,然后打印该行的剩余部分。将其放入变量中非常简单:
node=$(diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p')
或
read -r node < <(diskutil info "BOOTCAMP" | sed -ne '/Device Node:/s#.*/##p')
您可以像这样交替处理 awk
中的输出:
diskutil info "BOOTCAMP" | awk -F/ '/Device Node:/ { print $NF }'
这再次找到您感兴趣的行,并打印最后一个字段 .. 字段分隔符设置为正斜杠。
如果您真的只想为此使用 grep
,您可以进行一些管道安装:
diskutil info "BOOTCAMP" | grep 'Device Node:' | grep -o '/[^/]*$' | grep -Eo '[^/]+'
当然,如果您愿意,可以将最后的 grep
替换为 cut -d/ -f2
。
当然,如果 BOOTCAMP
不存在,所有这些都会失败。