找到文件然后cd到Linux中的该目录

时间:2010-08-11 12:57:14

标签: linux shell filesystems

在shell脚本中,如何按特定名称查找文件,然后导航到该目录以对其进行进一步操作?

从这里开始,我将把文件复制到另一个目录(但我可以将其添加到上下文中。)

11 个答案:

答案 0 :(得分:21)

您可以使用以下内容:

pax[/home/pax]> cd "$(dirname "$(find / -type f -name ls | head -1)")"
pax[/usr/bin]> _

这将找到第一个ls常规文件,然后切换到该目录。

就每一位的作用而言:

  • 搜索将从/开始,然后向下搜索,列出所有名为-type fls)的常规文件(-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
相关问题