Tilde扩大报价

我写了一个脚本,其中必须在用户定义的目录中find可能包含代字号的文件。 构造看起来像

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

我使用引号来覆盖该path中的可能空格,但根据手册页,代字符扩展不适用于引号。 我知道:操作符可能可以做这个扩展,但我不知道如何在这里使用它。

'user-defined-directory'从用户$ HOME目录中的另一个configuration文件中获取。 它不是作为parameter passing给我的脚本,而是从我编写的脚本中的另一个configuration中parsing出来的。

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

这个工作给出了一些相当合理的假设,但是它远不是明显的代码(也不是一个线性的):

 # 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处理不同的情况。 第一个条款处理一个值~并简单地replace$HOME 。 第二种是偏执狂: ~/映射到$HOME/ 。 第三个涉及~/anything (包括一个空的“任何东西”)。 下一个案例涉及~user 。 全面*处理所有其他事情。

请注意,代码使得( ~user不会扩展为包含任何双空格的值,也不包含任何制表符或换行符(可能还有其他类似空格的字符))的(似是而非的)假设。 如果你必须处理这个问题,生活将会变成地狱。

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

Tilde绝对不会在报价中扩大。 可能还有其他的bash技巧,但是我在这种情况下做的是这样的:

 find ~/"$user_defined_directory" -type f 

即移动开始~/外部报价,并保留在报价path的其余部分。