使用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/'