如何解决在shell中提取特定的子字符串
我有一个包含以下行的文件:
ro fstype=sd timeout=10 console=ttymxc1,115200 show=true
我想提取fstype属性“ sd”并将其存储在变量中。
我用bash完成了工作
IFS=" " read -a args <<< file
for arg in ${args[@]}; do
if [[ "$arg" =~ "fstype" ]]; then
id=$(cut -d "=" -f2 <<< "$arg")
echo $id
fi
done
,然后在另一个Shell脚本中执行awk命令:
awk -F " " '{print $2}' file | cut -d '=' -f2
由于'fstype'参数的位置和文件内容可能不同,如何在Shell脚本中执行相同的操作并保持兼容性?
解决方法
请您尝试以下。
awk 'match($0,/fstype=[^ ]*/){print substr($0,RSTART+7,RLENGTH-7)}' Input_file
或更具体地说,要处理=
之前的任何字符串,请尝试以下操作:
awk '
match($0,/fstype=[^ ]*/){
val=substr($0,RSTART,RLENGTH)
sub(/.*=/,"",val)
print val
val=""
}
' Input_file
使用sed
:
sed 's/.*fstype=\([^ ]*\).*/\1/' Input_file
awk
代码的解释:
awk ' ##Starting awk program from here.
match($0,/fstype=[^ ]*/){ ##Using match function to match regex fstype= till first space comes in current line.
val=substr($0,RLENGTH) ##Creating variable val which has sub-string of current line from RSTART to till RLENGTH.
sub(/.*=/,val) ##Substituting everything till = in value of val here.
print val ##Printing val here.
val="" ##Nullifying val here.
}
' Input_file ##mentioning Input_file name here.
,
每当您的数据中包含tag = value对时,我发现最好从创建一个将这些标签(名称)映射为其值的数组(下面的f[]
)开始
$ awk -v tag='fstype' -F'[ =]' '{for (i=2;i<NF;i+=2) f[$i]=$(i+1); print f[tag]}' file
sd
$ awk -v tag='console' -F'[ =]' '{for (i=2;i<NF;i+=2) f[$i]=$(i+1); print f[tag]}' file
ttymxc1,115200
通过上述方法,您可以对数据进行任何处理,只需将其名称引用为数组中的索引即可,例如:
$ awk -F'[ =]' '{
for (i=2;i<NF;i+=2) f[$i]=$(i+1)
if ( (f["show"] == "true") && (f["timeout"] < 20) ) {
print f["console"],f["fstype"]
}
}' file
ttymxc1,115200 sd
如果您的数据有多于一行,并且每行上可能有不同的字段(对于您的数据似乎不正确),则将delete f
添加为脚本的第一行。
如果键和值可以通过正则表达式fstype=[^ ]*
,grep
和-o
选项进行匹配,则提取匹配的模式。
$ grep -o 'fstype=[^ ]*' file
fstype=sd
此外,正则表达式\K
可以与-P
选项一起使用(请确保此选项仅在GNU grep
中有效)。
\K
左侧未显示模式。
因此,下面的表达式只能提取值。
-o
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。