我正在尝试将bash函数放在.bashrc
中。
这与我的想法一致......
FindGO ()
{
alias go=cd $(find -name $1 | egrep -o ".+\/"); #finds file and chops of name at end for cd to work
echo "file directory containing $1 now aliased to go";
}
我希望能帮助您实现这一目标(如果找不到文件,请输入错误消息)。
更新 我将保留当时的帮助。但如果有人想要真正做到这一点,请考虑FZF。
答案 0 :(得分:1)
别名真的很糟糕。您可以做的是在FindGO
函数中定义一个函数。这听起来很酷:
FindGO () {
local qfound
local found=$(find -name "$1" -printf '%h' -quit)
if [[ -z $found ]]; then
echo "Oh dear, I couldn't find \`$1' anywhere... and I really looked everywhere."
return 1
fi
printf -v qfound '%q' "$found"
eval "go() { cd \"$(pwd)\"/$qfound; }"
echo "Will change directory to the one containing \`$1' (namely \`$found') with the function go."
}
我知道,eval
是邪恶的,但它与安全引用的$qfound
变量一起使用。
find
与-printf '%h'
一起使用,只会输出文件的目录部分(以免grep
变得无用)。-quit
开关,以便find
在第一个找到的文件后立即退出。这会加快速度!如果你想在有多个找到的文件时想要一些特殊的东西,你可以调整它(但要注意你将如何获得find
的输出,以便它可以与任何名字中带有任何有趣符号的文件一起使用)。found
引用printf
目录,以便我可以安全地eval
定义go
功能。FindGO
的执行时间计算出来的,这样每次你想find
时都不会调用另一个go
(我相信这是一个很酷的功能......如果你不这样做,请告诉我们我们可以改变它。这就是eval
的原因。这是这个剧本中非常重要的一部分。实际上,这就是为什么这部分的解释被埋没在无聊的清单中间。find
而不是locate
?享受!
编辑。愚蠢的我当然在例如mkdir $'\n'; touch $'\n/lalala'
时失败了。这是治愈方法:在find中使用bash的printf '%q'
:
FindGO () {
local qfound=$(find -name "$1" -exec bash -c 'printf "%q" "$1"' _ {} \; -quit)
if [[ -z $qfound ]]; then
echo "Oh dear, I couldn't find \`$1' anywhere... and I really looked everywhere."
return 1
fi
eval "go() { cd \"$(pwd)\"/$qfound; }"
echo "Will change directory to the one containing \`$1' (namely \`$qfound') with the function go."
}
Edit2。我发誓,写下前两个版本的人非常愚蠢。因为这是 解决方案。如果你读到(并理解)到这里,你可能已经学到了一些有趣的东西。这里有更多:
FindGO () {
local qfound=$(find -name "$1" -execdir bash -c 'printf "%q" "$PWD"' {} \; -quit);
if [[ -z $qfound ]]; then
echo "Oh dear, I couldn't find \`$1' anywhere... and I really looked everywhere.";
return 1;
fi;
eval "go() { cd $qfound; }";
echo "Will change directory to the one containing \`$1' (namely \`$qfound') with the function go.";
}
正如你所看到的,解决方案是绝对明显的,理智的,明确的,没有错综复杂的,优雅的。因为它应该始终是:
find
与-execdir
标记一起使用,并请求bash很好地printf '%q'
其$PWD
(注意:我要求变量 $PWD
,而不是命令pwd
的输出,因为如果目录名以换行符结尾,这将失败。)哇。我喜欢这个!干杯。
答案 1 :(得分:0)
怎么样:
findGO()
{
TMP=$PWD
PLACE=$(find . -iname $1 | egrep -o ".+\/")
alias go="cd $TMP/${PLACE:2:${#PLACE}}"
cd $PLACE
echo "$TMP/${PLACE:2:${#PLACE}} now aliased to go"
}
这也可能有所帮助: http://www.tecmint.com/35-practical-examples-of-linux-find-command/
答案 2 :(得分:0)
你很亲密,你真正需要的只是你的命令的粗略版本是逃避或引用cd
和$(...
之间的空格。这是一个更加文件名安全的版本:
foo ()
{
alias go="cd '$(dirname "$(find . -name "$1" -print -quit)")'"
echo "file directory containing $1 now aliased to go"
}
内心的一些解释:
[1] find . -name "$1" -print -quit
# Find the first file named by the argument, print it
# and quit so we don't get too many files.
[2] dirname "$([1])"
# Execute the aforementioned command, capture its output, and
# pass it as the argument to `dirname`.
# `dirname` simply cuts off the end of the string from the
# last / it finds through the end.
alias go="cd '$([2])'"
# Alias `go` to cd to the output of the previous command
# (directory containing first file found).
# Put in quotes in case there are any funny characters.
# Will break if there is a single quote in the name, but that can't be helped in bash.