我有一个脚本试图从gparted获取信息块.
我的数据看起来像:
Disk /dev/sda: 42.9GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 316MB 315MB primary ext4 boot
2 316MB 38.7GB 38.4GB primary ext4
3 38.7GB 42.9GB 4228MB primary linux-swap(v1)
log4net.xml
Model: VMware Virtual disk (scsi)
Disk /dev/sdb: 42.9GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 316MB 315MB primary ext4 boot
5 316MB 38.7GB 38.4GB primary ext4
6 38.7GB 42.9GB 4228MB primary linux-swap(v1)
Run Code Online (Sandbox Code Playgroud)
我使用正则表达式将其分解为两个磁盘块
^磁盘(/ dev [\ S] +):((?!磁盘)[\ s\S])*
这适用于多线.
当我在bash脚本中测试它时,我似乎无法匹配\ s,或者\ S - 我做错了什么?
我通过以下脚本测试:
data=`cat disks.txt`
morematches=1
x=0
regex="^Disk (/dev[\S]+):((?!Disk)[\s\S])*"
if [[ $data =~ $regex ]]; then
echo "Matched"
while [ $morematches == 1 ]
do
x=$[x+1]
if [[ ${BASH_REMATCH[x]} != "" ]]; then
echo $x "matched" ${BASH_REMATCH[x]}
else
echo $x "Did not match"
morematches=0;
fi
done
fi
Run Code Online (Sandbox Code Playgroud)
但是,当我逐步测试正则表达式的部分时,每当我匹配\ s或\ S时,它都不起作用 - 我做错了什么?
kon*_*box 22
也许不支持\ S和\ s,或者你不能放置它们[ ]
.请尝试使用此格式:
^Disk[[:space:]]+/dev[^[:space:]]+:[[:space:]]+[^[:space:]]+
Run Code Online (Sandbox Code Playgroud)
编辑
看来你真的想得到匹配的字段.我使脚本更简单,但我不确定它是否是你的预期输出:
#!/bin/bash
regex='^Disk[[:space:]]+(/dev[^[:space:]]+):[[:space:]]+(.*)'
while read line; do
[[ $line =~ $regex ]] && echo "${BASH_REMATCH[1]} matches ${BASH_REMATCH[2]}."
done < disks.txt
Run Code Online (Sandbox Code Playgroud)
哪个产生
/dev/sda matches 42.9GB.
/dev/sdb matches 42.9GB.
Run Code Online (Sandbox Code Playgroud)
tri*_*eee 11
因为这是一个常见的 FAQ,让我列出一些 Bash 不支持的结构,以及如何解决它们,这里有一个简单的解决方法。
有多种常用的正则表达式方言。Bash 支持的是扩展正则表达式的一种变体。这与例如许多在线正则表达式测试器支持的不同,后者通常是更现代的 Perl 5 / PCRE 变体。
\d
\D
\s
\S
\w
\W
-这些可以与POSIX字符类等同替换[[:digit:]]
,[^[:digit:]]
,[[:space:]]
,[^[:space:]]
,[_[:alnum:]]
,和[^_[:alnum:]]
,分别。(请注意最后一种情况,其中[:alnum:]
POSIX 字符类用下划线扩充以完全等同于 Perl\w
速记。)a.*?b
用类似的东西替换,a[^ab]*b
以在实践中获得类似的效果,尽管两者并不完全等效。(?:...)
。在微不足道的情况下,只需使用捕获括号(...)
;当然,如果您使用捕获组和/或反向引用,这将重新编号您的捕获组。(?<=before)
or 之类的环视(?!after)
,实际上任何东西(?
都是 Perl 扩展。对于这些没有简单的通用解决方法,尽管您通常可以将问题重新表述为可以避免环顾的问题。