使用bash / cut / split提取一部分string
我有这样的string:
/var/cpanel/users/joebloggs:DNS9=domain.com
我需要从这个string中提取用户名:joebloggs并将其存储在一个variables中
除了joebloggs和domain.com之外,string的格式总是相同的,所以我想这个string可以用“cut”分割两次?
首先拆分将使用的string分割:我们将第一部分存储在一个varibale传递给第二个拆分函数。
第二次拆分将使用/拆分string,并将最后一个字(joebloggs)存储到variables中
我知道如何做到这一点在PHP中使用数组和分裂,但在bash我有点失落。
在bash中使用参数扩展从这个string中提取joebloggs
,而没有任何额外的过程…
MYVAR="/var/cpanel/users/joebloggs:DNS9=domain.com" NAME=${MYVAR%:*} # retain the part before the colon NAME=${NAME##*/} # retain the part after the last slash echo $NAME
不依赖于joebloggs
在path中的特定深度。
如果你想使用grep
进行一些过度的操作:
echo MYVAR | grep -oE '/[^/]+:' | cut -c2- | rev | cut -c2- | rev
概要
几个参数扩展模式的概述,供参考…
${MYVAR#pattern} # delete shortest match of pattern from the beginning ${MYVAR##pattern} # delete longest match of pattern from the beginning ${MYVAR%pattern} # delete shortest match of pattern from the end ${MYVAR%%pattern} # delete longest match of pattern from the end
所以#
从一开始就表示匹配(考虑注释行), %
表示从结尾开始。 一个实例意味着最短,两个意味着最长。
你也可以用下面的代码来replace特定的string
${MYVAR/search/replace}
该pattern
与文件名匹配的格式相同,所以*
(任何字符)是常见的,通常后跟特定的符号,如/
或.
例子:
给定一个像
MYVAR="users/joebloggs/domain.com"
删除保留文件名的path(所有字符都是斜线):
echo ${MYVAR##*/} domain.com
删除文件名,留下path(删除最后一个/
最后一个):
echo ${MYVAR%/*} users/joebloggs
获取文件扩展名(删除前一段时间):
echo ${MYVAR##*.} com
注:要执行两个操作,您不能将它们组合,但必须分配给一个中间variables。 所以要获取没有path或扩展名的文件名:
NAME=${MYVAR##*/} # remove part before last slash echo ${NAME%.*} # from the new var remove the part after the last period domain
定义一个这样的函数:
getUserName() { echo $1 | cut -d : -f 1 | xargs basename }
并传递string作为参数:
userName=$(getUserName "/var/cpanel/users/joebloggs:DNS9=domain.com") echo $userName
那sed呢? 这将在一个命令中工作:
sed 's#.*/\([^:]*\).*#\1#' <<<$string
-
#
正被用于正则expression式分隔符,而不是/
因为string有/
。 -
.*/
抓取string到最后一个反斜杠。 -
\( .. \)
标记一个捕获组。 这是\([^:]*\)
。-
[^:]
表示任何字符(除了冒号),*
表示零或多个。
-
-
.*
表示该行的其余部分。 -
\1
意味着替代第一个(也是唯一)捕获组中发现的内容。 这是名字。
以下是将该string与正则expression式匹配的细分:
/var/cpanel/users/ joebloggs :DNS9=domain.com joebloggs sed 's#.*/ \([^:]*\) .* #\1 #'
使用单个Awk:
... | awk -F '[/:]' '{print $5}'
也就是说,使用字段分隔符:
/
或:
,用户名始终在字段5中。
将其存储在一个variables中:
username=$(... | awk -F '[/:]' '{print $5}')
使用sed
更灵活的实现,不需要用户sed
段5:
... | sed -es/:.*// -es?.*/??
也就是说,删除所有内容,并将其删除,直到最后一个。 sed
可能比awk
更快,所以这个select肯定更好。
使用一个sed
echo "/var/cpanel/users/joebloggs:DNS9=domain.com" | sed 's/.*\/\(.*\):.*/\1/'