列出所有没有给定文件名的文件的目录


12

如何列出所有没有给定文件名的文件的目录?例如给定这棵树

/
  /a
     README
     file001
     file002
  /b
     README
     file001
  /c
     file003

我想列出没有命名文件的目录README,在这种情况下,它将是directory /c。我该怎么办?我想不出任何使用eg的语法find


羞羞哦,你甚至没有搜索:askubuntu.com/questions/196960/...
SLM

我搜索时可能没有想到正确的关键字。
Renan

2
我只是在你的扒手。我去过很多次,我想不出合适的词来寻找东西8-)。
slm

Answers:


5

假设find像GNU find这样的实现接受{}嵌入到以下参数的参数-exec

$ find . -type d \! -exec test -e '{}/README' \; -print

这里的目录1/1至5/5具有自述文件,其他目录为空。

$ tree 
.
|-- 1
|   `-- 1
|       `-- README
|-- 10
|   `-- 10
|-- 2
|   `-- 2
|       `-- README
|-- 3
|   `-- 3
|       `-- README
|-- 4
|   `-- 4
|       `-- README
|-- 5
|   `-- 5
|       `-- README
|-- 6
|   `-- 6
|-- 7
|   `-- 7
|-- 8
|   `-- 8
`-- 9
    `-- 9

现在,当我们运行此版本的find命令时:

$ find . -type d \! -exec test -e '{}/README' \; -print
.
./10
./10/10
./7
./7/7
./9
./9/9
./6
./6/6
./5
./8
./8/8
./4
./1
./3
./2

参考文献


如何修改命令以搜索没有特定文件扩展名(例如* .txt)的子目录。用* .txt修改自述文件似乎不起作用
WanderingMind

@WanderingMind-如果您有新问题,请在网站上作为新问题提出;-)
slm

3

您可以使用-exec选项find检查文件,然后打印所有检查失败的结果。

find /path/to/base -mindepth 1 -maxdepth 1 -type d -exec test -e {}/README \; -o -print

3

不需要find。只需使用外壳:

for d in */; do [ -f "$d"README ] || printf '%s\n' "$d"; done
c/

如果您需要递归,则可以使用(对于bashzsh默认情况下,可以set -o globstar在中使用ksh93):

shopt -s globstar
for d in **/; do [ -f "$d"README ] || printf '%s\n' "$d"; done

(请注意,默认情况下不包含点文件)。


2

With zshGlob限定词e字符串):

print -rl -- *(/e_'[[ ! -f $REPLY/README ]]'_)

要么

print -rl -- *(/^e_'[[ -f $REPLY/README ]]'_)

添加D以包含隐藏目录:

print -rl -- *(D/e_'[[ ! -f $REPLY/README ]]'_)

/仅选择目录,并仅e_'[[ ! -f $REPLY/README ]]'_选择引号之间的外壳程序代码返回的true目录名称$REPLY,即对于glob *(/)扩展到的每个目录名称(),[[ ! -f $REPLY/README ]]如果结果为,它将运行并保留目录名称true
第二种形式^e_'.....'_使用相同的glob限定符,取反(但这次条件表达式不取反:)[[ -f $REPLY/README ]]


上面只会返回当前目录中的目录名称。
如果要递归搜索(同样,要包含隐藏目录,请添加D限定符):

print -rl ./**/*(/e_'[[ ! -f $REPLY/README ]]'_)

2

可移植地,您可以执行以下操作:

find . -type d -exec sh -c '
  for dir do
    [ -f "$dir/README" ] || printf "%s\n" "$dir"
  done' sh '{}' +

[ -f file ]测试文件是否存在 并被确认为常规文件(在符号链接解析之后)。

如果您想测试它仅存在(作为该目录中的条目),而不论其类型如何,都需要:[ -e file ] || [ -L file ],尽管请注意,您需要对该目录具有搜索权限才能执行这些测试。您可能需要添加一些[ -x "$dir" ]测试来解决这些情况,例如:

find . -type d -exec sh -c '
  for dir do
    if [ -x "$dir" ]; then
      [ -f "$dir/README" ] || printf "%s\n" "$dir"
    else
      printf >&2 "Cannot tell for \"%s\"\n" "$dir"
    fi
  done' sh '{}' +

或为避免竞争状况,请使用zsh

find . -type d -exec zsh -c '
  zmodload zsh/system
  for dir do
    ERRNO=0
    if [ ! -f "$dir/README" ]; then
      if [ "$errnos[ERRNO]" = ENOENT ]; then
        printf "%s\n" "$dir"
      else
        syserror -p "ERROR: $dir/README: "
      fi
    fi
  done' zsh '{}' +

另请参见如何确定Bash中是否不存在常规文件?在这样。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.