我有一个这样的字符串:
/var/cpanel/users/joebloggs:DNS9=domain.com
我需要从此字符串中提取用户名(joebloggs
)并将其存储在变量中。
除了joebloggs
和domain.com
之外,字符串的格式始终相同,所以我认为字符串可以使用cut
拆分两次?
第一次拆分将由:
拆分,我们会将第一部分存储在变量中以传递给第二个拆分函数。
第二次拆分将按/
拆分并将最后一个字(joebloggs
)存储到变量中
我知道如何使用数组和拆分在php中执行此操作,但我在bash中有点迷失。
答案 0 :(得分:240)
使用参数扩展从bash中的此字符串中提取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
在路径的特定深度。
<强>摘要强>
一些参数扩展模式的概述,供参考......
${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
所以#
表示从头开始匹配(考虑注释行),%
表示从结尾开始。一个实例意味着最短,两个实例意味着最长。
您可以使用数字来获取基于位置的子串:
${MYVAR:3} # Remove the first three chars (leaving 4..end)
${MYVAR::3} # Return the first three characters
${MYVAR:3:5} # The next five characters after removing the first 3 (chars 4-9)
您还可以使用以下方法替换特定字符串或模式:
${MYVAR/search/replace}
pattern
的格式与文件名匹配的格式相同,因此*
(任何字符)都很常见,通常后跟特定符号,例如/
或{{1} }
<强>示例:强>
给出像
这样的变量.
删除留下文件名的路径(所有字符都为斜杠):
MYVAR="users/joebloggs/domain.com"
删除文件名,保留路径(删除最后echo ${MYVAR##*/}
domain.com
后的最短匹配):
/
获取文件扩展名(在上一期之前删除所有内容):
echo ${MYVAR%/*}
users/joebloggs
注意:要执行两项操作,您无法将它们组合在一起,但必须分配给中间变量。所以要获取没有路径或扩展名的文件名:
echo ${MYVAR##*.}
com
答案 1 :(得分:34)
定义一个这样的函数:
getUserName() {
echo $1 | cut -d : -f 1 | xargs basename
}
并将字符串作为参数传递:
userName=$(getUserName "/var/cpanel/users/joebloggs:DNS9=domain.com")
echo $userName
答案 2 :(得分:18)
sed怎么样?这将在一个命令中起作用:
sed 's#.*/\([^:]*\).*#\1#' <<<$string
#
用于正则表达式分隔符而不是/
,因为字符串中包含/
。.*/
将字符串抓取到最后一个反斜杠。\( .. \)
标记了一个捕获组。这是\([^:]*\)
。
[^:]
表示任何字符_除了冒号,而*
表示零或更多。.*
表示该行的其余部分。\1
表示替换第一个(也是唯一一个)捕获组中的内容。这就是名字。这里是将字符串与正则表达式匹配的细分:
/var/cpanel/users/ joebloggs :DNS9=domain.com joebloggs
sed 's#.*/ \([^:]*\) .* #\1 #'
答案 3 :(得分:10)
使用单个sed
echo "/var/cpanel/users/joebloggs:DNS9=domain.com" | sed 's/.*\/\(.*\):.*/\1/'
答案 4 :(得分:9)
使用单个Awk:
... | awk -F '[/:]' '{print $5}'
也就是说,使用/
或:
作为字段分隔符,用户名始终位于字段5中。
将其存储在变量中:
username=$(... | awk -F '[/:]' '{print $5}')
使用sed
的更灵活的实施,不要求用户名为字段5:
... | sed -e s/:.*// -e s?.*/??
即,删除:
及更高版本中的所有内容,然后删除所有内容,直到最后/
。 sed
可能比awk
更快,所以这个选择肯定更好。