我正在目录中查找文件,因此我使用 find 命令,然后显示该文件所在的目录路径。
前任。
$find . -name file.txt
/folder/path/file-contents/file.txt
现在我想知道是否有一种方法可以比复制路径目录然后使用 cd 命令并粘贴目录更快地进入该目录?
另外,如果使用 find 命令后列出了两个路径,是否有办法仅 cd 到给定的第二个路径,而无需复制和粘贴该路径?
只是想知道能帮助我加快终端工作速度。
答案1
(bash
进一步向下变化)
在shell 中,可以通过将 globbing 限定符添加到模式的末尾来zsh
获得 globbing 模式的最后一个匹配。([-1])
在此示例中,我们查找名称以 结尾的文件.sh
:
$ print -rC1 ./**/*.sh
./local/sbin/scheduled-backup.sh
./local/sbin/update-cvs.sh
./local/sbin/update-system.sh
./local/sbin/zerofill.sh
$ print -rC1 ./**/*.sh(.D[-1])
./local/sbin/zerofill.sh
限定符中添加的.
andD
确保我们只找到常规文件,并且还匹配隐藏名称(与dotglob
中设置的一样bash
)。
这可用于更改到包含找到的文件的目录:
$ cd ./**/*.sh(.D[-1]:h)
(这里使用 csh/vi 样式:h
修饰符来获取头文件的(目录名))
作为采用文件名(而不是模式)的 shell 函数:
goto_file () cd ./**/$1(.D[-1]:h)
这不依赖于文件名是否正常(不包含换行符等)
在 中bash
,假设您首先使用 设置globstar
和dotglob
shell 选项shopt -s globstar dotglob
,您可以分两步执行类似的操作:
$ set -- ./**/*.sh
$ cd "$( dirname -- "${@: -1}" )"
这将位置参数设置为匹配路径名的列表,然后在调用中使用最后一个dirname
,并将其结果与 一起使用cd
。但使用 时bash
,不能保证 glob 的扩展将是常规文件。
显然你可以使用命名数组来代替:
$ stuff=( ./**/*.sh )
$ cd "$( dirname -- "${stuff[-1]}" )"
作为 shell 函数,获取文件名(而不是模式):
goto_file () {
local pathnames
pathnames=( ./**/"$1" )
cd "$( dirname -- "${pathnames[-1]}" )"
}
这要求至少globstar
已在调用 shell 中设置了该选项。不过我们可以根据需要进行设置:
goto_file () {
local pathnames
if [[ $BASHOPTS != *globstar* ]]; then
shopt -s globstar
trap 'shopt -u globstar' RETURN # unset globstar on return
fi
pathnames=( ./**/"$1" )
cd "$( dirname -- "${pathnames[-1]}" )"
}
与变体一样,这zsh
不会依赖于文件名是否正常(不包含换行符等),但目录名称不能以换行符结尾,因为当命令dirname
替换返回其值时,这些字符将被删除。
答案2
您可以使用它dirname
来获取保存您正在搜索的文件的目录名称,并且可以使用它tail -1
来获取最后一个条目。从技术上讲head -2 | tail -1
,只要有两个或更多,您就可以用来获取第二个列表。如果只有 1 个列表,它将返回 1。
喜欢:
cd $(dirname $(find . -name file.txt | tail -1))
或者:
cd $(dirname $(find . -name file.txt | head -2 | tail -1))
我不确定这是否真的更快,但它确实减轻了使用鼠标选择文本并复制它的麻烦。
您可以将其构建到 shell rc 中的函数中,例如.bashrc
.
function goto-file() {
file=$1
cd $(dirname $(find . -name $file | tail -1))
}
然后,您的 CLI 效率将是简单地键入goto-file file.txt
。
也许更好的办法是允许您通过您想要搜索的路径?这是我刚刚添加到我的函数中的函数.bashrc
:
function goto-file() {
if [ $# -gt 2 -o $# -lt 1 ]; then
echo "Usage: goto-file [path] filename"
else
if [ $# -eq 2 ]; then
path=$1
file=$2
elif [ $# -eq 1 ]; then
path='.'
file=$1
fi
cd $(dirname $(find $path -name $file | tail -1))
fi
}
相当方便。谢谢。
答案3
如果您使用xterm
终端模拟器,您可以绑定dabbrev-expand()
行动(模仿emacs
'动态缩写功能)到某个键。
例如,放入一个资源文件(要么加载到 X 服务器中,xrdb
以便xterm
该 X 服务器的任何客户端都受到影响,要么放入一个XENVIRONMENT
文件中,以便从计算机进行所有 xterm 调用,无论它们连接到哪个 X 服务器)受影响),例如:
XTerm.VT100.translations: #override\
Meta <KeyPress> /: dabbrev-expand()
然后使用Alt+/,xterm
根据屏幕上显示的内容提供补全(从最靠近光标的内容开始)。
因此,在find ...
显示后,键入for将其扩展 为,然后删除尾随部分(或者使用、append或 use (如果配置为将其视为单词分隔符,例如使用)/folder/path/file-contents/file.txt
就足够了。cd /
Alt+/xterm
/
/folder/path/file-contents/file.txt
zsh
(:h)
Ctrl+W/
select-word-style
如果路径包含空格或控制字符或分解形式的字符,则该方法将不起作用。
如果它包含 shell 特有的字符(例如'
, "
, ;
, &
...),您需要引用它们(在 中zsh
,您可以使用quote-region
小部件(Alt+"默认情况下绑定到这样做))。
答案4
你可以试试cdi
(https://github.com/antonioolf/cdi)
创建此命令行工具是为了改善目录浏览体验(替代cd
)。
它基本上是一个交互式命令行目录浏览器。
您所需要做的就是运行cdi
命令,使用箭头键导航文件夹(Right进入文件夹,Left返回Up并Down滚动列表),当您找到所需的目录时,只需按一下即可执行Enter真正的命令。cd
查看存储库