如何打破shell脚本中的string

我有以下格式的数据库名称

username_databasename 

现在我想把单独的数据库备份放在用户名目录中

 /backups/username/backup 

我怎样才能从那个string中获得usernamae

我也希望如果string不包含下划线(_),那么备份应该去

 /backups/others/backup 

你可以做:

 username=others if echo $name | grep '_'; then username=$(echo $name | cut -d'_' -f 1) fi 

您可以在以下方面使用变体:

 case $fullname in (*_*) username=$(echo $fullname | sed 's/_.*//');; (*) username=others;; esac backupdir="/backups/$username/backup" 

Jonathan Leffler有一个很好的,干净的答案。

如果你不想使用sed出于某种原因,你可以把$(echo | sed)替换成:

 username="${fullname%_*}" 

它做同样的事情。

在bash中,你可以使用数组,像这样:

 str="a/bc/def" IFS="/" arr=($str) echo ${arr[0]}; # prints 'a' echo ${arr[1]}; # prints 'bc' echo ${arr[2]}; # prints 'def' echo ${arr[@]}; # prints 'a bc def' 

如果你想通过不同的“分隔符”来分割字符串,只需将IFS =“/”行更改为该分隔符,例如

 str="a,bc,def" IFS="," arr=($str) 

这里不需要cutgrepsedawk 。 只需使用bash的内置参数替换:

 db_name=username_databasename username=others if [[ ${db_name} =~ '_' ]]; then username=${db_name%%_*} fi backup_dir=/backups/${username}/backup 

我宁愿每个脚本只使用一种语言,尽可能少的分叉:-)

你可以使用awk:

 username = `echo $name | awk -F"_" '{print $1}'` 

对于一个纯粹的解决方案,没有可能的昂贵的外部程序调用(只有当你做了很多,这可能不是这样):

 pax> export x=a ; if [[ "${x%%_*}" != "${x}" ]]; then ...> export bkpdir=/backups/${x%%_*}/backup ...> else ...> export bkpdir=/backups/others/backup ...> fi pax> echo " ${bkpdir}" /backups/others/backup pax> export x=a_b ; if [[ "${x%%_*}" != "${x}" ]]; then ...> export bkpdir=/backups/${x%%_*}/backup ...> else ...> export bkpdir=/backups/others/backup ...> fi pax> echo " ${bkpdir}" /backups/a/backup 

if语句通过检查修改后的字符串来检测是否有下划线。 如果有下划线,则会有所不同。

${x%%_*}给你的字符串直到删除最长的_*模式(换句话说,它删除了从第一个下划线到结束的所有内容)。


稍微简单的变体是:

 export bkpdir=/backups/others/backup if [[ "${x%%_*}" != "${x}" ]]; then export bkpdir=/backups/${x%%_*}/backup fi