Shell 避免在“查找”成功时进入子目录

Shell 避免在“查找”成功时进入子目录,shell,find,Shell,Find,我试图在多个文件夹中查找某个文件。当我点击文件时,我想停止进入子目录。 例如: /foo/.target /bar/buz/.target /foo/bar/.target 我只想要前两个: /foo/.target /bar/buz/.target find ... | sed 2q find ... | awk '1; NR == 2 { exit }" 你的要求并不完全清楚。我的理解是:在目录树中查找“通缉”文件;如果目录直接包含至少一个匹配项,则只需打印它们,否则将递归

我试图在多个文件夹中查找某个文件。当我点击文件时,我想停止进入子目录。 例如:

/foo/.target  
/bar/buz/.target  
/foo/bar/.target
我只想要前两个:

/foo/.target  
/bar/buz/.target
find ... | sed 2q
find ... | awk '1; NR == 2 { exit }"

你的要求并不完全清楚。我的理解是:在目录树中查找“通缉”文件;如果目录直接包含至少一个匹配项,则只需打印它们,否则将递归到该目录中

我想不出一个纯粹的解决办法。您可以编写一个awk或perl脚本来解析find的输出

这是一个shell脚本,我认为它符合您的要求。警告:我只进行了最低限度的测试

#!/bin/sh

## Return 0 if $1 is a matching file, 1 otherwise.
## Note that $1 is the full path to the file.
wanted () {
  case ${1##*/} in
    .target) true;;
  esac
}

## Recurse into the directory $1. Print all wanted files in this directory.
## If there is no wanted file, recurse into each subdirectory in turn.
traverse () {
  found=0
  for x in "$1"/.* "$1"/*; do
    if [ "$x" = "$1/." ] || [ "$x" = "$1/.." ]; then
      continue # skip '.' and '..' entries
    fi
    if ! [ -e "$x" ]; then
      continue # skip spurious '.*', '*' from non-matching patterns
    fi
    if wanted "$x"; then
      printf '%s\n' "$x"
      found=$(($found+1))
    fi
  done
  if [ $found -eq 0 ]; then # no match here, so recurse
    for x in "$1"/.*/ "$1"/*/; do
      x=${x%/}
      if [ "$x" = "$1/." ] || [ "$x" = "$1/.." ]; then
        continue
      fi
      if [ -d "$x" ]; then # only actual subdirs, not symlinks or '.*' or '*'
        found_stack=$found:$found_stack # no lexical scoping in sh
        traverse "${x%/}"
        found=${found_stack%%:*}
        found_stack=${found_stack#*:}
      fi
    done
  fi
}

found_stack=:
for x; do
  if wanted "$x"; then
    printf '%s\n' "$x"
  else
    traverse "$x"
  fi
done
使用sed或awk或任何可能在管道从输入读取一行时破坏管道的东西。它可能会很快或至少足够快地停止find的执行

find ... | sed 1q
find ... | awk '1; { exit }"
它只显示一行

对于前两项:

/foo/.target  
/bar/buz/.target
find ... | sed 2q
find ... | awk '1; NR == 2 { exit }"

你真的需要停止吗,或者你只是不想要它的输出?如果它停止会更好,但是在输出中删除它们也可以。