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

发布于 2024-09-14 08:27:28 字数 104 浏览 5 评论 0原文

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

从这里我将把文件复制到另一个目录(但我已经可以做到这一点,只需将其添加到上下文中即可。)

In a shell script how would I find a file by a particular name and then navigate to that directory to do further operations on it?

From here I am going to copy the file across to another directory (but I can do that already just adding it in for context.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

叹梦 2024-09-21 08:27:49

cd -- "$(sudo find / -type d -iname "dir name gone here" 2>/dev/null)"

保留所有引号(这只是将您发送到您想要的目录想要,之后你就可以在后面输入命令)

cd -- "$(sudo find / -type d -iname "dir name goes here" 2>/dev/null)"

keep all quotes (all this does is just send you to the directory you want, after that you can just put commands after that)

莫言歌 2024-09-21 08:27:46

试试这个。我创建这个是为了自己使用。

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

try this. i created this for my own use.

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
孤芳又自赏 2024-09-21 08:27:45

如果您的文件仅位于一个位置,您可以尝试以下

操作: cd "$(find ~/ -name [filename] -exec dirname {} \;)" && ...

您可以使用 -exec 使用 find 返回的路径(位于 {} 占位符所在的位置)调用 dirname是)。这将改变目录。您还可以添加双与号 ( && ) 以在 shell 更改目录后执行下一个命令。

例如:
cd "$(find ~/ -name need_to_find_this.rb -exec dirname {} \;)" && ruby need_to_find_this.rb

它将查找该 ruby​​ 文件,更改到该目录,然后从该文件夹中运行它。此示例假设文件名是唯一的,并且由于某种原因,ruby 脚本必须从其目录中运行。如果文件名不唯一,您将获得许多传递给 cd 的位置,它将返回错误,然后不会更改目录

If your file is only in one location you could try the following:

cd "$(find ~/ -name [filename] -exec dirname {} \;)" && ...

You can use -exec to invoke dirname with the path that find returns (which goes where the {} placeholder is). That will change directories. You can also add double ampersands ( && ) to execute the next command after the shell has changed directory.

For example:
cd "$(find ~/ -name need_to_find_this.rb -exec dirname {} \;)" && ruby need_to_find_this.rb

It will look for that ruby file, change to the directory, then run it from within that folder. This example assumes the filename is unique and that for some reason the ruby script has to run from within its directory. If the filename is not unique you'll get many locations passed to cd, it will return an error then it won't change directories.

狼性发作 2024-09-21 08:27:44

如果它是您的 PATH 中的程序,您可以执行以下操作:

cd "$(dirname "$(which ls)")"

或在 Bash 中执行以下操作:

cd "$(dirname "$(type -P ls)")"

它使用较少的外部可执行文件。

这不使用外部:

dest=$(type -P ls); cd "${dest%/*}"

If it's a program in your PATH, you can do:

cd "$(dirname "$(which ls)")"

or in Bash:

cd "$(dirname "$(type -P ls)")"

which uses one less external executable.

This uses no externals:

dest=$(type -P ls); cd "${dest%/*}"
入怼 2024-09-21 08:27:43

就这么简单,是不是很优雅呢?

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}
}

Simply this way, isn't this elegant?

cdf yourfile.py

Of course you need to set it up first, but you need to do this only once:

Add following line into your .bashrc or .zshrc, whatever you use as your shell initialization script.

source ~/bin/cdf.sh 

And add this code into ~/bin/cdf.sh file that you need to create from scratch.

#!/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}
}
少跟Wǒ拽 2024-09-21 08:27:42
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

}
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

}
万人眼中万个我 2024-09-21 08:27:41

如果您只是查找文件然后将其移动到其他地方,只需使用 find 和 -exec

find /path -type f -iname "mytext.txt" -exec mv "{}" /destination +;

if you are just finding the file and then moving it elsewhere, just use find and -exec

find /path -type f -iname "mytext.txt" -exec mv "{}" /destination +;
川水往事 2024-09-21 08:27:39

基于这个答案对于类似的问题,其他有用的选择可能是有 2 个命令,第一个命令查找文件,第二个命令导航到其目录:

find ./ -name "champions.txt"
cd "$(dirname "$(!!)")"

其中 !! 是历史扩展,意思是“上一个命令”。

Based on this answer to a similar question, other useful choice could be having 2 commands, 1st to find the file and 2nd to navigate to its directory:

find ./ -name "champions.txt"
cd "$(dirname "$(!!)")"

Where !! is history expansion meaning 'the previous command'.

许你一世情深 2024-09-21 08:27:36

如果您想迭代导航到 find 定位的每个文件并在每个目录中执行操作,请扩展已经给出的答案:

for i in $(find /path/to/search/root -name filename -type f)
do (
  cd $(dirname $(realpath $i));
  your_commands;
)
done

Expanding on answers already given, if you'd like to navigate iteratively to every file that find locates and perform operations in each directory:

for i in $(find /path/to/search/root -name filename -type f)
do (
  cd $(dirname $(realpath $i));
  your_commands;
)
done
末蓝 2024-09-21 08:27:35

没有人建议定位(对于大树来说这要快得多)?

兹什:

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$"))

no one suggesting locate (which is much quicker for huge trees) ?

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$"))
渔村楼浪 2024-09-21 08:27:34

您可以使用类似的内容:

cd -- "$(dirname "$(find / -type f -name ls | head -1)")"

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

就每一位的作用而言:

  • find将从/开始并向下搜索,列出所有名为的常规文件(-type fls-name ls)。您还可以向 find 添加其他内容,以进一步限制您获取的文件。
  • <代码>| head -1 将过滤掉除第一行之外的所有行。
  • $() 是一种获取命令输出并将其放在另一个命令的命令行上的方法。
  • dirname 可以获取完整的文件规范并为您提供路径位。
  • cd 仅更改该目录,-- 用于防止将以连字符开头的目录名称视为 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]> _

You can use something like:

cd -- "$(dirname "$(find / -type f -name ls | head -1)")"

This will locate the first ls regular file then change to that directory.

In terms of what each bit does:

  • The find will start at / and search down, listing out all regular files (-type f) called ls (-name ls). There are other things you can add to find to further restrict the files you get.
  • The | head -1 will filter out all but the first line.
  • $() is a way to take the output of a command and put it on the command line for another command.
  • dirname can take a full file specification and give you the path bit.
  • cd just changes to that directory, the -- is used to prevent treating a directory name beginning with a hyphen from being treated as an option to cd.

If you execute each bit in sequence, you can see what happens:

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]> _
回首观望 2024-09-21 08:27:34

以下应该更安全:

cd -- "$(find / -name ls -type f -printf '%h' -quit)"

优点:

  • 双破折号可以防止将以连字符开头的目录名解释为选项(find 不会生成此类文件名,但它没有害处,可能会类似结构所需)
  • -name-type 检查之前检查,因为后者有时需要 stat
  • 不需要 dirname因为 %h 说明符已经打印目录名称
  • -quit 以在找到第一个文件后停止搜索,因此不需要 head ,这会导致脚本在包含换行符的目录名上失败

The following should be more safe:

cd -- "$(find / -name ls -type f -printf '%h' -quit)"

Advantages:

  • The double dash prevents the interpretation of a directory name starting with a hyphen as an option (find doesn't produce such file names, but it's not harmful and might be required for similar constructs)
  • -name check before -type check because the latter sometimes requires a stat
  • No dirname required because the %h specifier already prints the directory name
  • -quit to stop the search after the first file found, thus no head required which would cause the script to fail on directory names containing newlines
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文