使用bash / cut / split提取字符串的一部分

时间:2013-10-20 19:56:35

标签: string bash

我有一个这样的字符串:

/var/cpanel/users/joebloggs:DNS9=domain.com

我需要从此字符串中提取用户名(joebloggs)并将其存储在变量中。

除了joebloggsdomain.com之外,字符串的格式始终相同,所以我认为字符串可以使用cut拆分两次?

第一次拆分将由:拆分,我们会将第一部分存储在变量中以传递给第二个拆分函数。

第二次拆分将按/拆分并将最后一个字(joebloggs)存储到变量中

我知道如何使用数组和拆分在php中执行此操作,但我在bash中有点迷失。

5 个答案:

答案 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更快,所以这个选择肯定更好。