在当前工作目录的最近祖先中查找特定文件

在当前工作目录的最近祖先中查找特定文件

我想找到一种通过查找来查找给定文件的方法向上在目录结构中,而不是递归地搜索子目录。

有一个节点模块似乎完全符合我的要求,但我不想依赖于安装 JavaScript 或类似的包。有没有一个 shell 命令可以做到这一点?有办法做到find这一点吗?或者我无法通过谷歌搜索找到的标准方法?

答案1

这是直接翻译的查找配置算法在通用 shell 命令中(在 bash、ksh 和 zsh 下测试),我使用返回码 0 表示成功,使用 1 表示 NULL/失败。

findconfig() {
  # from: https://www.npmjs.com/package/find-config#algorithm
  # 1. If X/file.ext exists and is a regular file, return it. STOP
  # 2. If X has a parent directory, change X to parent. GO TO 1
  # 3. Return NULL.

  if [ -f "$1" ]; then
    printf '%s\n' "${PWD%/}/$1"
  elif [ "$PWD" = / ]; then
    false
  else
    # a subshell so that we don't affect the caller's $PWD
    (cd .. && findconfig "$1")
  fi
}

示例运行,复制并扩展了窃取的设置史蒂芬·哈里斯的回答:

$ mkdir -p ~/tmp/iconoclast
$ cd ~/tmp/iconoclast
$ mkdir -p A/B/C/D/E/F A/good/show 
$ touch A/good/show/this A/B/C/D/E/F/srchup A/B/C/thefile 
$ cd A/B/C/D/E/F
$ findconfig thefile
/home/jeff/tmp/iconoclast/A/B/C/thefile
$ echo "$?"
0
$ findconfig foobar
$ echo "$?"
1

答案2

检查当前目录的简单循环,如果找不到,则删除最后一个组件将起作用

#!/bin/bash

wantfile="$1"

dir=$(realpath .)

found=""

while [ -z "$found" -a -n "$dir" ]
do
  if [ -e "$dir/$wantfile" ]
  then
    found="$dir/$wantfile"
  fi
  dir=${dir%/*}
done

if [ -z "$found" ]
then
  echo Can not find: $wantfile
else
  echo Found: $found
fi

例如,如果这是目录树:

$ find /tmp/A
/tmp/A
/tmp/A/good
/tmp/A/good/show
/tmp/A/good/show/this
/tmp/A/B
/tmp/A/B/C
/tmp/A/B/C/thefile
/tmp/A/B/C/D
/tmp/A/B/C/D/E
/tmp/A/B/C/D/E/F
/tmp/A/B/C/D/E/F/srchup

$ pwd      
/tmp/A/B/C/D/E/F

$ ./srchup thefile
Found: /tmp/A/B/C/thefile

我们可以看到搜索沿着树向上进行,直到找到我们要查找的内容。

答案3

一种方法是:

#! /bin/sh
dir=$(pwd -P)
while [ -n "$dir" -a ! -f "$dir/$1" ]; do
    dir=${dir%/*}
done
if [ -f "$dir/$1" ]; then printf '%s\n' "$dir/$1"; fi

如果您想跟踪符号链接而不是检查物理目录,请替换pwd -P为。pwd -L

相关内容