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的其余部分。