如何导航到shell脚本中的子目录

时间:2010-11-24 07:53:10

标签: shell

我有一个目录。这个目录有很多子目录,其中包含html页面和一些c源代码文件,Makefile等。我试图编写的脚本将从一个具有所有这些子目录的目录执行。 以下是您可以看到的目录和文件集

ls
delete.sh  lddbus   Makefile      misc-progs  sbull  scullc  scullp  short       simple  snull  usb
include    LICENSE  misc-modules  pci         scull  sculld  scullv  shortprint  skull   tty

其中一些是目录,一些是上面子目录中的文件,还有我想要消除的其他子目录和html页面。 手动方式是进入每个目录并通过以下命令删除页面

rm *.html*

由于html页面的名称以?=/something种名称结尾。 所以我决定写一个shell脚本。 但我不清楚的是如何在我的shell脚本中将目录名称作为参数。如果我决定使用for循环或类似的东西。 在这种情况下,我该怎么办? 我不想用

find . -name '*.html*' -exec rm -f {} \;

因为我这样做是为了学习目的。

5 个答案:

答案 0 :(得分:2)

此代码段将为当前目录中的每个子目录运行ls

for d in * .[!.]* ..?*; do
    test -d "${d}" && ls "${d}"
done

您可以调整它以运行您喜欢的每个子目录的命令。

如果您希望深入了解目录层次结构,可以将此代码包装在一个函数中,并为每个子目录重新运行它。

function f {
    cd "$1"
    # do something in this dir
    for d in * .[!.]* ..?*; do
        cd "$1"
        test -d "$1/$d" && f "$1/$d"
    done
}

f "`pwd`"

对于Zsh,您可能想要设置NULL_GLOB选项(-G开关),因此如果没有隐藏的目录,它不会报告错误,在Bash中它默认工作。

答案 1 :(得分:2)

使用bash 4(或zsh),您可以使用globstar“**”来递归匹配。

shopt -s globstar
echo **/*html*

使用如下目录设置:

mkdir -p {a..b}/{c..d}
touch {a..b}/{c..d}/{e..f}.{htmlx,other}

这将导致:

a/c/e.htmlx a/c/f.htmlx a/d/e.htmlx a/d/f.htmlx b/c/e.htmlx b/c/f.htmlx b/d/e.htmlx b/d/f.htmlx

答案 2 :(得分:1)

find是要走的路。选择错误的方法来解决问题,你将无法学到任何有用的东西。

打印要删除的文件列表

find /your/dir -type f -iname '*.html*'

并删除它们

find /your/dir -type f -iname '*.html*' -delete

find是一个强大的命令,学会使用它。

改进您不想使用的命令的另一种方法:

find /your/dir -type f -name '*.html*' -exec rm -f {} +

(提示:man find了解-exec ;-exec +的区别)

请注意,shell脚本只是以最有用的方式使用findcatlswc等小型程序。彻底了解这些实用程序是学习shell脚本的必要条件。

答案 3 :(得分:0)

创建一个这样的函数:

myfunc()
{
  for dir; do
      if [[ -d "$dir" ]]; then
          echo rm -rf "${dir}/*.html*"
      else
          echo "No such dir '$dir'"
      fi
  done
}

然后通过从

传递要删除 .html 的目录来调用该函数

输出

$ myfunc /foo /etc /root
No such dir '/foo'
rm -rf /etc/*.html*
rm -rf /root/*.html*

对输出感到满意后,请移除echo以使其真正删除文件。

答案 4 :(得分:0)

这基于maarons' answer,但有两个优点:

  • */循环中使用*代替for意味着它只会迭代目录而不是所有文件以获得潜在的大加速
  • 使用pushdpopd可以轻松支持.或不支持参数来表示当前目录。

这是功能:

g () {
    local d bb=/dev/null # bit-bucket
    pushd "$1" > $bb
    pwd    # do something (pwd is a placeholder)
    for d in */
    do
        test -d "$PWD/$d" && g "$PWD/$d"    # you could use $(pwd) instead of $PWD
    done
    popd > $bb
}

当然,将find-execdir一起使用会更简单,并会得到相同的结果。

find -mindepth 1 -type d -execdir sh -c 'cd {}; pwd' \;    # (pwd` is a placeholder)