在shell脚本中,如何按特定名称查找文件,然后导航到该目录以对其进行进一步操作?
从这里开始,我将把文件复制到另一个目录(但我可以将其添加到上下文中。)
答案 0 :(得分:21)
您可以使用以下内容:
pax[/home/pax]> cd "$(dirname "$(find / -type f -name ls | head -1)")"
pax[/usr/bin]> _
这将找到第一个ls
常规文件,然后切换到该目录。
就每一位的作用而言:
/
开始,然后向下搜索,列出所有名为-type f
(ls
)的常规文件(-name ls
)。您还可以向find
添加其他内容以进一步限制所获得的文件。head -1
的管道将过滤除第一个以外的所有。$()
是一种获取命令输出并将其放在另一个命令的命令行上的方法。dirname
可以采用完整的文件规范并为您提供路径位。cd
只需更改该目录。如果按顺序执行每一位,您可以看到会发生什么:
pax[/home/pax]> find / -type f -name ls
/usr/bin/ls
pax[/home/pax]> find / -type f -name ls | head -1
/usr/bin/ls
pax[/home/pax]> dirname "$(find / -type f -name ls | head -1)"
/usr/bin
pax[/home/pax]> cd "$(dirname "$(find / -type f -name ls | head -1)")"
pax[/usr/bin]> _
答案 1 :(得分:10)
以下应该更安全:
cd -- "$(find / -name ls -type f -printf '%h' -quit)"
优点:
find
不会产生此类文件名,但它没有害处,可能是类似构造所必需的)-name
在-type
检查之前检查,因为后者有时需要stat
dirname
因为%h
说明符已经打印了目录名-quit
在找到第一个文件后停止搜索,因此不需要head
会导致脚本在包含换行符的目录名称上失败答案 2 :(得分:3)
基于this answer基于类似问题,其他有用的选择可能是有2个命令,第一个用于查找文件,第二个用于导航到其目录:
find ./ -name "champions.txt"
cd "$(dirname "$(!!)")"
其中!!
是历史扩展意义'前一个命令'。
答案 3 :(得分:3)
没有人建议定位(这对于大树来说要快得多)?
的zsh:
cd $(locate zoo.txt|head -1)(:h)
cd ${$(locate zoo.txt)[1]:h}
cd ${$(locate -r "/zoo.txt$")[1]:h}
or could be slow
cd **/zoo.txt(:h)
bash:
cd $(dirname $(locate -l1 -r "/zoo.txt$"))
答案 4 :(得分:1)
如果您只是找到该文件然后将其移动到其他位置,只需使用find和-exec
即可find /path -type f -iname "mytext.txt" -exec mv "{}" /destination +;
答案 5 :(得分:1)
function fReturnFilepathOfContainingDirectory {
#fReturnFilepathOfContainingDirectory_2012.0709.18:19
#$1=File
local vlFl
local vlGwkdvlFl
local vlItrtn
local vlPrdct
vlFl=$1
vlGwkdvlFl=`echo $vlFl | gawk -F/ '{ $NF="" ; print $0 }'`
for vlItrtn in `echo $vlGwkdvlFl` ;do
vlPrdct=`echo $vlPrdct'/'$vlItrtn`
done
echo $vlPrdct
}
答案 6 :(得分:1)
扩展已经给出的答案,如果您想迭代导航到find
找到并在每个目录中执行操作的每个文件:
for i in $(find /path/to/search/root -name filename -type f)
do (
cd $(dirname $(realpath $i));
your_commands;
)
done
答案 7 :(得分:0)
如果是PATH
中的某个程序,您可以执行以下操作:
cd "$(dirname "$(which ls)")"
或在Bash:
cd "$(dirname "$(type -P ls)")"
使用少一个外部可执行文件。
这不使用外部:
dest=$(type -P ls); cd "${dest%/*}"
答案 8 :(得分:0)
就这样,这不是优雅吗?
cdf yourfile.py
当然你需要先设置它,但你需要这样做只有:
将以下行添加到.bashrc或.zshrc中,无论您将哪个用作shell初始化脚本。
source ~/bin/cdf.sh
将此代码添加到需要从头创建的〜/ bin / cdf.sh文件中。
#!/bin/bash
function cdf() {
THEFILE=$1
echo "cd into directory of ${THEFILE}"
# For Mac, replace find with mdfind to get it a lot faster. And it does not need args ". -name" part.
THEDIR=$(find . -name ${THEFILE} |head -1 |grep -Eo "/[ /._A-Za-z0-9\-]+/")
cd ${THEDIR}
}
答案 9 :(得分:0)
如果您的文件只在一个位置,您可以尝试以下操作:
cd "$(find ~/ -name [filename] -exec dirname {} \;)" && ...
您可以使用-exec
使用查找返回的路径(dirname
占位符所在的位置)调用{}
。这将改变目录。在shell更改目录后,您还可以添加双&符号(&&
)来执行下一个命令。
例如:
cd "$(find ~/ -name need_to_find_this.rb -exec dirname {} \;)" && ruby need_to_find_this.rb
它将查找该ruby文件,切换到该目录,然后从该文件夹中运行它。此示例假定文件名是唯一的,并且由于某种原因,ruby脚本必须从其目录中运行。如果文件名不是唯一的,那么您将获得许多传递给cd的位置,它将返回错误,然后它不会更改目录。
答案 10 :(得分:0)
尝试一下。我创建了这个供我自己使用。
cd ~
touch mycd
sudo chmod +x mycd
nano mycd
cd $( ./mycd search_directory target_directory )"
if [ $1 == '--help' ]
then
echo -e "usage: cd \$( ./mycd \$1 \$2 )"
echo -e "usage: cd \$( ./mycd search_directory target_directory )"
else
find "$1"/ -name "$2" -type d -exec echo {} \; -quit
fi