Tilde扩展报价

tij*_*agi 4 bash

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

found_files=$(find "$user_defined_directory" -type f … )
Run Code Online (Sandbox Code Playgroud)

我使用引号来覆盖该路径中的可能空格,但根据手册页,波形扩展在引号中不起作用.我知道:运营商可能会进行这种扩展,但我无法弄清楚如何在这里使用它.

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

Jon*_*ler 6

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

# 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]"
Run Code Online (Sandbox Code Playgroud)

在我的机器上运行时(有用户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]
Run Code Online (Sandbox Code Playgroud)

该功能tilde_expansion分别以不同方式处理各种情况.第一个条款涉及一个值~,只是替代$HOME.第二个是偏执的情况:~/被映射到$HOME/.第三个处理~/anything(包括空的'任何').下一个案例涉及~user.*所有其他东西都能解决所有问题.

请注意,代码使得(似乎合理的)假设~user不会扩展为包含任何双空格的值,也不会扩展为任何制表符或换行符(可能还有其他类似空格的字符).如果你必须处理这个问题,生活就会变得很糟糕.

请注意chdir()主目录的答案,这解释了POSIX需要~扩展到当前值$HOME,但是~user从密码数据库扩展到主目录的值.


Gor*_*son 5

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