【问题标题】:Searching through multiple directories in bash在bash中搜索多个目录
【发布时间】:2023-04-07 01:48:01
【问题描述】:

我试图弄清楚如何搜索多个使用 pushd 定义的目录,以查找列表中文件夹的磁盘空间,以及是否有任何文件夹是符号链接。现在我有一些效率很低的 for 循环不能在多个目录上工作(如果只有一个,它工作得很好,但是一旦我开始用 pushd 定义多个工作目录,它就会搞砸了)。

更新:

$COMPARE 的内容供参考:

COMPARE=`comm -23 "$HOMEOUT" "$USEROUT" |
            comm -23 - <(
                for f in "${FILTER[@]}"; do
                    echo "$f"
                done | sort)`

这是我的代码和执行时的结果:

DIRS=`ls -lah / | grep home | awk '{ print $9 }'`

 for i in "$DIRS"; do
    pushd /$i/ >/dev/null
 done

# Find the disk space of each folder

for x in "$DIRS"; do
        du -s /$x/$COMPARE | sort -n | cut -f 2-|xargs -i du -sh {}
done


# Check for and output symlinks
SYM=`for y in "$COMPARE"; do
    find /$DIRS/$y -maxdepth 1 -type l -print
done`

结果:

+ DIRS='home
home2
home3
old_home'
+ for i in '"$DIRS"'
+ pushd /home home2 home3 old_home/
+ for x in '"$DIRS"'
+ sort -n
+ du -s /home home2 home3 old_home/someuser someuser2 someuser3 someuser4
+ cut -f 2-
+ xargs -i du -sh '{}'

如您所见,这不起作用,因为我希望它像这样搜索列表中的每个用户(取决于他们的文件夹所在的位置):

/home/用户 /home/user2 /home2/user3 /home3/user4

有人可以提出一种更好/更有效的方法来实际工作吗?总的来说,我想弄清楚如何才能浓缩这一点。

Bash 版本:

GNU bash,版本 3.2.25(1)-release-(x86_64-redhat-linux-gnu)

提前致谢!

【问题讨论】:

  • 为什么要将目录推送到目录堆栈?此外,无需创建DIRS 变量;只需使用for i in /home/*; do
  • 这似乎是在 bash 脚本中拥有多个工作目录的最佳方式,因为我想搜索服务器上找到的任何 /home* 目录。如果不是这样,我愿意采用更好的方法来做到这一点。
  • 目录栈只是让切换到以前使用的工作目录更容易;一次只有一个工作目录。你从不使用堆栈,因为你从不调用cdpopd。但是,您也永远不会使用工作目录,因为您总是将要搜索的目录作为显式参数传递给 dufind
  • 您不必在目录中才能阅读它。
  • 下一个问题:$COMPARE 是什么?

标签: linux bash unix scripting centos


【解决方案1】:

"$DIRS" 将扩展为 "home home2 ...",因此 for 会将其视为单个令牌。不要解析ls,它非常脆弱。使用:

for x in /*home*; do
    du -sh "$x" | sort -h
done

(请注意,sort -h 是一个 gnu 扩展,但是当您使用 redhat 时,您应该拥有它)。
你还没有向我们展示你是如何构造$COMPARE,但我认为你正在寻找这个而不是第二个循环:

find /*home*/* -maxdepth 1 -type l

如果你只想要一些用户,你必须向我们展示你是如何构造$COMPARE的;您可能希望将其设为数组并使用find /*home*/"${COMPARE[@]}" ...


通过将() 包裹在() 中,将COMPARE 构造为一个数组。

IFS=$'\n' COMPARE=($(comm -23 "$HOMEOUT" "$USEROUT" |
            comm -23 - <(printf "%s\n" "${FILTER[@]}" | sort))

并使用它:

find /*home*/"${COMPARE[@]}" -maxdepth 1 -type l

【讨论】:

  • 我更新了我的问题,以便您更清楚地了解 $COMPARE 发生了什么。
  • IFS 会导致结果中的路径出现乱码,如下所示:/home/i''oforg - COMPARE 中修改后的代码在我的 shell 中无法正常工作。此外, sort -h 无法识别。不过,我至少在正确的轨道上。
  • 您的 bash 版本说它(至少已编译)在 redhat 上。这真的是你的系统吗?
  • @Striketh 如果您的 COMPARE 内容没有空格,您可以删除 IFS,但您是否确保包含前导 $,即 $'\n',而不是 '\n'
  • 我完全按照您的说明复制了您的代码,所以它就在那里。一旦我尝试使用它,我稍后就会在脚本中开始出现语法错误,所以有些东西是关闭的。排序版本为:sort (GNU coreutils) 5.97
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
  • 1970-01-01
  • 2013-11-01
相关资源
最近更新 更多