首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Bash Shell脚本:读取文件夹、修改日期并按月列出它们

Bash Shell脚本:读取文件夹、修改日期并按月列出它们
EN

Stack Overflow用户
提问于 2018-09-12 23:53:58
回答 1查看 218关注 0票数 0

我希望能够读取文件夹中的一堆文件夹,并从最近/当前月份(12 most )开始,每月列出它们,并由浏览器中的水平标尺分隔。谢谢!

代码语言:javascript
运行
复制
for directory in $(find . -maxdepth 1 -type d -print | egrep -v "^\.$")
 do
    date_file=$(date -r $directory +"%B")
    echo '<div class="month_txt">'$date_file'</div>' >>  $FILE
    echo '<hr />' >>  $FILE
    echo '<div class="folder">'$directory'</div>' >>  $FILE 
done

阅读:

FOLDER_A FOLDER_B FOLDER_C FOLDER_D FOLDER_E

输出:

8月: FOLDER_A FOLDER_C

9月: FOLDER_D

12月: FOLDER_E

一月: FOLDER_B

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-13 06:27:59

如果我正确理解了你的要求,不如:

代码语言:javascript
运行
复制
#!/bin/bash

FILE="./test.html"

declare -A ym2mo    # map "1809" to "September"
declare -A dirlist  # list of dirname for each yymm
declare -a ymlist   # list of yymm like "1809" ...

while read -r yymm month dir; do
    if [ -z "${ym2mo[$yymm]}" ]; then
        ym2mo[$yymm]="$month"
        ymlist+=("$yymm")
        dirlist[$yymm]="$dir"
    else
        dirlist[$yymm]+=" $dir"
    fi
done < <(
# a process substitution to generate a list of dirs and sort them
# as newest in top and oldest in bottom.
# Then the result is fed to the while loop above.
for dir in $(find . -maxdepth 1 -type d -exec basename {} \; | egrep -v "^\.$"); do
    month=$(date -r $dir +%B)
    yymm=$(date -r $dir +%y%m)
    echo "$yymm" "$month" "$dir"
done | sort -r -k1)

# finally generate the html fragment
for yymm in ${ymlist[@]}; do
    cat << EOS >> "$FILE"
    <div class="month_txt">"${ym2mo[$yymm]}"</div>
    <hr />
    <div class="folder">"${dirlist[$yymm]}"</div>
EOS
done

解释:

关键问题是我们如何按月(反向)时间顺序对列表进行排序。我引入了一个临时字段yymm,它以"1809“作为”2018年9月“的”1809“,在每个数字中保存年份和月份,这样我们就可以使用它作为键对列表进行排序。

另一个技巧是进程替换,以抑制创建临时文件,只为了排序列表。

希望这能有所帮助。

如果declare -A由于bash版本而不能工作,下面是使用AWK的另一种选择:

代码语言:javascript
运行
复制
#!/bin/bash

FILE="./test.html"

for dir in $(find . -maxdepth 1 -type d -exec basename {} \; | egrep -v "^\.$"); do
    month=$(date -r $dir +%B)
    yymm=$(date -r $dir +%y%m)
    echo "$yymm" "$month" "$dir"
done | sort -r -k1 | awk '{
    # gather the list
    if ($1 in ym2mo) {
        dirlist[$1] = dirlist[$1] " " $3
    } else {
        ym2mo[$1] = $2
        dirlist[$1] = $3
        ymlist = ymlist " " $1
    }
}
END {
    # format and print the result
    len = split(ymlist, ary)
    for (i = 1; i <= len; i++) {
        yymm = ary[i]
        print "<div class=\"month_txt\">" ym2mo[yymm] "</div>"
        print "<hr />"
        print "<div class=\"folder\">" dirlist[yymm] "</div>"
    }
}' >> $FILE

下面的代码演示了如何将shell变量值传递给AWK脚本:

代码语言:javascript
运行
复制
#!/bin/bash

FILE="./test.html"
hrefpath="/path/to/the/href"
newdir="mynewdir"

for dir in $(find . -maxdepth 1 -type d -exec basename {} \; | egrep -v "^\.$"); do
    month=$(date -r $dir +%B)
    yymm=$(date -r $dir +%y%m)
    echo "$yymm" "$month" "$dir"
done | sort -r -k1 | awk -v param1="$hrefpath" -v param2="$newdir" '{
    # see the line above how you can pass shell variable values to AWK.
    # you can refer to param1 and param2 in the lines below.
    # add "-v var=val" pairs if you need more.
    if ($1 in ym2mo) {
        dirlist[$1] = dirlist[$1] " " $3
    } else {
        ym2mo[$1] = $2
        dirlist[$1] = $3
        ymlist = ymlist " " $1
    }
}
END {
    len = split(ymlist, ary)
    for (i = 1; i <= len; i++) {
        yymm = ary[i]
        print "<div class=\"month_txt\">" ym2mo[yymm] "</div>"
        print "<hr />"
        print "<div class=\"folder\">" dirlist[yymm] "</div>"
        print "<a href=\"" param1 "\"><img src=\"" param2 "/thumb.jpg\" height=\"250\" width=\"300\"/></a>"
    }
}' >> $FILE

最后,这里是没有关联数组的纯bash版本:

代码语言:javascript
运行
复制
#!/bin/bash

FILE="./test.html"

print_html() {
    cat << EOS >> "$3"
    <div class="month_txt">"$1"</div>
    <hr />
    <div class="folder">"$2"</div>
EOS
}

while read -r p1 p2 p3; do
    if [ -z "$prev_p1" ]; then              # 1st line
        month="$p2"
        dir="$p3"
    elif [ "$p1" = "$prev_p1" ]; then       # same month as prev line
        dir="$dir $p3"
    else
        print_html "$month" "$dir" "$FILE"
        month="$p2"
        dir="$p3"
    fi
    prev_p1="$p1"                   # keep yymm value for next

done < <(
for dir in $(find . -maxdepth 1 -type d -exec basename {} \; | egrep -v "^\.$"); do
    month=$(date -r $dir +%B)
    yymm=$(date -r $dir +%y%m)
    echo "$yymm" "$month" "$dir"
done | sort -r -k1
)
print_html "$month" "$dir" "$FILE"  # flush the last line
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52304878

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档