5

我编写了一个脚本,其中必须在用户定义的目录中找到一些文件,这些文件可能包含波浪号(因此,可能有user_defined_directory='~/foo')。构造看起来像

found_files=$(find "$user_defined_directory" -type f … )

我使用引号来覆盖该路径中的可能空格,但根据手册页,波浪号扩展在引号中不起作用。我知道:可能可以进行这种扩展的运算符,但我不知道如何在这里使用它。

'user-defined-directory' 取自用户 $HOME 目录中的另一个配置文件。它没有作为参数传递给我的脚本,而是从我编写的脚本中的另一个配置中解析出来的。

4

3 回答 3

7

您可以使用"${user_defined_directory/#~/$HOME}"当前用户的主目录替换字符串开头的“~”。请注意,这不会处理~username/subdir格式,只会处理普通的~. 如果您需要处理更复杂的版本,则需要编写一个更复杂的转换器。

于 2013-04-07T05:26:25.660 回答
7

给出一些相当合理的假设,这是可行的,但它远非显而易见的代码(也不是单行代码):

# Working function - painful, but can you simplify any of it?
# NB: Assumes that ~user does not expand to a name with double spaces or
#     tabs or newlines, etc.

expand_tilde()
{
    case "$1" in
    (\~)        echo "$HOME";;
    (\~/*)      echo "$HOME/${1#\~/}";;
    (\~[^/]*/*) local user=$(eval echo ${1%%/*})
                echo "$user/${1#*/}";;
    (\~[^/]*)   eval echo ${1};;
    (*)         echo "$1";;
    esac
}

# Test cases

name1="~/Documents/over  enthusiastic"
name2="~crl/Documents/double  spaced"
name3="/work/whiffle/two  spaces  are  better  than one"

expand_tilde "$name1"
expand_tilde "$name2"
expand_tilde "$name3"
expand_tilde "~"
expand_tilde "~/"
expand_tilde "~crl"
expand_tilde "~crl/"

# This is illustrative of the 'normal use' of expand_tilde function
x=$(expand_tilde "$name1")
echo "x=[$x]"

在我的机器(有用户crl)上运行时,输出为:

/Users/jleffler/Documents/over  enthusiastic
/Users/crl/Documents/double  spaced
/work/whiffle/two  spaces  are  better  than one
/Users/jleffler
/Users/jleffler/
/Users/crl
/Users/crl/
x=[/Users/jleffler/Documents/over  enthusiastic]

该函数tilde_expansion分别以不同的方式处理各种情况。第一个子句处理一个值~并简单地替换$HOME。第二种是偏执狂:~/被映射到$HOME/. 第三个处理~/anything(包括一个空的“任何东西”)。下一个案例处理~user. 包罗万象的*处理其他一切。

请注意,代码做出了(似是而非的)假设,即~user不会扩展为包含任何双空格、任何制表符或换行符(可能还有其他类似空格的字符)的值。如果你不得不面对它,生活将是地狱。

注意chdir()home directory的答案,它解释了 POSIX 需要~扩展为 的当前值$HOME,但~user扩展为密码数据库中的主目录的值。

于 2013-04-07T06:35:02.673 回答
2

波浪号绝对不会在引号内展开。可能还有其他一些 bash 技巧,但我在这种情况下所做的是:

find ~/"$user_defined_directory" -type f

即从~/引号外开始移动并将其余路径保留在引号中。

于 2013-04-07T04:20:44.847 回答