【问题标题】:In ksh how do I iterate through a list of directories and cd to them using a loop?在 ksh 中,如何使用循环遍历目录列表并 cd 到它们?
【发布时间】:2016-03-08 19:54:39
【问题描述】:

基本上我有一个这样设置的平面文件:

/this/is/a/log/目录 | 30

/this/also/is/have/logs | 45

/this/logs/也 | 60

我要做的是提取此平面文件的第一列,即目录路径,并检查其中是否有超过 500 个日志文件。如果是,请删除除最新的 500 个文件之外的所有文件。

我试图做这样的事情

#!/bin/ksh

for each in "$(awk '{ print $1 }' flat_file)"; do

    cd "$each";

    if [ "ls -l | wc -l >= 500" ]; then
        rm `ls -t | awk 'NR>500'`

    else
        :

    fi

done

但是从我读到的内容来看,我不能像我试图做的那样使用 for 循环从我的脚本中 cd 并且你可以从一个函数中执行它,此时我基本上只是创建了一个函数并复制了它代码,它当然没有工作(不太熟悉shell脚本)。类似于 Python 的 OS 模块的东西,我可以使用 os.listdir() 并传入目录名称,这将是完美的,但我还没有找到一种简单的方法来做到这一点。

【问题讨论】:

    标签: shell loops scripting ksh cd


    【解决方案1】:

    好的,你在正确的轨道上,但你会将查看你代码的csh 程序员与for each 混淆。为什么不

     for dir in $( awk '{ print $1 }' flat_file ) ; do
          cd "$dir"
          if (( $(ls -l | wc -l) >= 500 )); then
                rm $( ls -t | awk 'NR>500' )
             fi
          cd -
     done
    

    您的原始代码中有很多小东西。为什么有时使用反引号,而其他时候使用首选形式的 cmd-sub $( cmd )

    "$(awk '{print $1}' file)" 括在 dbl-quotes 中会将 cmd-substition 的完整输出转换为 1 个长字符串,它不会找到名为“dir1 dir2 dir3 ....dirn”的目录,对吗?

    您不需要空值 (:) else。您可以删除该代码块。

    ksh 支持 (( .... )) 对内的数学运算(就像 bash)。

    cd - 会带你回到上一个目录。

    学习使用 shell 调试/跟踪,set -vx。它会首先向您展示将要执行的内容(有时是一个非常大的循环结构),然后它将显示执行的每一行,前面是 + 以及变量已转换为它们的值的位置。您可能还想使用export PS4='$LINENO >',以便调试将显示当前正在执行的 lineNo。

    IHTH

    【讨论】:

    • 啊,这很好用。这是我在 shell 中编写的第一件事,也是我在 Python 中唯一的其他经验,您可以或多或少地互换 " " 和 ' ' ,因此仍然掌握所有语法差异的窍门。就我的 else 声明而言,这只是一个占位符,因为我稍后会在其中扔一些东西。无论如何,非常感谢您提供的信息,可能比 set -vx 更重要,它可以帮助我直观地看到正在发生的事情,这将有助于我在未来找出我做错了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 2021-04-24
    相关资源
    最近更新 更多