你是如何做到的?我在工作中的code/
目录中,按文件夹、子文件夹和子子文件夹的顺序组织了所有脚本或程序,以便于我定期运行。
PATH=${PATH}:$(find ~/code -type d | tr '\n' ':' | sed 's/:$//')
这将在当前路径下附加您~/code树中的每个目录。我不喜欢这个想法,更喜欢只有几个目录保存我的可执行文件,并明确列出它们,但因人而异。
如果您想排除所有隐藏的目录,基本上需要剥离每个具有序列"/."的行(以确保您不会检查隐藏目录下的子目录):PATH=${PATH}:$(find ~/code -type d | sed '/\/\\./d' | tr '\n' ':' | sed 's/:$//')
这将防止您获取像~/code/level1/.hidden/level3/
这样的目录(即,一旦检测到它们是隐藏的,就停止在子树中搜索)。如果您只想排除隐藏的目录,但仍允许它们下面的非隐藏目录,请使用:
PATH=${PATH}:$(find ~/code -type d -name '[^\.]*' | tr '\n' ':' | sed 's/:$//')
这将允许~/code/level1/.hidden2/level3/
,但不允许~/code/level1/.hidden2/.hidden3/
,因为-name
只检查文件的基本名称,而不是完整的路径名。
以下代码可以正确地处理隐藏目录及其子目录,并能够处理名字中包含换行符或其他空白字符的情况,同时也会将空白字符去除:
export PATH="${PATH}$(find ~/code -name '.*' -prune -o -type d -printf ':%p')"
我使用类似的技巧来自动设置CLASSPATH
。
PATH=$PATH$(find ~/code -name '.*' -prune -o -type f -a -perm /u+x -printf ':%h\n' | sort | uniq | tr -d '\n')
[ -s ~/.codepath ] && export PATH=$PATH$(<~/.codepath)
并运行
find ~/code -name '.*' -prune -o -type f -a -perm /u+x -printf ':%h\n' |sort |uniq |tr -d '\n' > ~/.codepath
find ~/code -name '.*' -prune -o -type f -a -perm /u+x -print | sed 's@/[^/]\+$@:@' | sort | uniq | tr -d '\n' | sed 's/^/:/; s/:$//'
类似于这样的东西
my_path=$(find $root -type d | tr '\n' ':')
或者
my_path=$(find $root -type d -printf '%p:')
find "$root" -name ".[a-z]*" -prune -o -type d -printf '%p:'
,以排除与给定模式匹配的点文件(排除.
是不明智的,而给定的技巧是一个可行的80%解决方案,以避免它)。 - Charles Duffy我也一直在寻找解决这个问题的方法。如果bash有一种方式可以指定对于某些路径,你希望它递归地搜索文件,那将是非常好的。例如:
PATH="$PATH:/usr/local/bin:~/bin**"
~/bin
会搜索该目录及其所有子目录,而不会使您的 PATH
变量混乱。
由于这个功能没有实现,我的临时解决方案是将所有内容放在我的 bin 目录中,然后创建另一个目录 "bindir",其中包含指向 "bin" 中实际可执行文件的符号链接,但它们被整齐地排列到子目录中,以便更容易找到它们。
我的唯一问题是是否应该使用硬链接而不是符号链接。
**
运算符。您需要先在某些地方启用它:shopt -s globstar
你可以接着做
echo **
递归地回显当前目录下所有后代文件。
注意,有时它会在过于复杂的目录中退出,所以请在最低的递归点使用 **。
echo **/
巧合的是,递归地发出所有目录名称,仅限目录名称。(不包括当前目录)
echo ./**/
包括当前目录。(顺便提一下,它也跳过隐藏的目录)
因此,这应该适用于创建路径字符串:
echo ./**/ | sed 's/\s\s*/:/g'
如果您不想使用相对路径,
echo $PWD/**/ | sed 's/\s\s*/:/g'
从您在其他帖子中的评论中可以看出,您想要类似于“确认”提供的行为。如果您打算使用查找+grep组合,则此工具通常更高效且更易于用于此任务。
示例:
# search for 'mystring' in all c++ files recursively ( excluding SCM dirs and backup files )
ack "mystring" --type=cpp
# finds all text files not in an SCM dir ( recursively) and not a backup using type heuristics.
ack -f --type=text
echo "hello world" | sed 's/\s/x/'
会输出helloxworld
。 - Kent Fredric\s
。请使用[[:space:]]
代替\s
:( - Kent Fredricsed
最小功能的标准应该是什么样子的。 - Charles Duffypaths=( **/ ); oIFS="$IFS"; IFS=':'; CLASSPATH=${paths[*]}; IFS="$oIFS"
。 - Charles Duffy类似这样:
_path="$(
find <path> -name '.*' -prune -o -type d -print
)"
[[ $_path ]] && _path="${_path//$'\n'/:}" PATH="$PATH:${_path%:}"
-printf ':%p'
。export PATH="$PATH:$(du "~/code/" | cut -f2 | tr '\n' ':' | sed 's/:*$//')"
du
会显示每行的所有子目录信息cut -f2
将提取第二列,即子目录的名称tr '\n' ':'
将每个换行符更改为冒号。这将把所有行连接成一行,并且子目录由冒号分隔sed 's/:*$//'
将删除最后一个冒号我有一个单独的bin
目录$HOME/bin
,里面安装了我构建的任何程序的副本(或脚本、或指向程序或脚本的符号链接)。目前它里面有近 600 个命令(ls | wc -l
统计出来是 604,但由于各种原因,还有十几个子目录)。
当我测试程序时,我会在构建它的地方执行它;一旦我暂时完成测试,我会用我的acquire
脚本来获取
它,该脚本将文件复制并设置其权限。
这样留给我的就是一个整洁漂亮的配置文件(我不使用.bashrc
;我宁愿在登录 shell 启动时进行一次设置,子 shell 继承工作环境而无需再解析.bashrc
),但却是一个相当笨重的bin
目录。例如,它避免了每次 shell 启动时重置 PATH 的成本,鉴于我的路径设置代码多么复杂,这真是太好了!