bash - Bash Shell 脚本:读取文件夹修改日期并按月列出
问题描述
我希望能够读取文件夹中的一堆文件夹,并从最近/当前月份(12mos)开始每月列出它们,并在浏览器中用水平标尺分隔。?谢谢!
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
十二月:FOLDER_E
一月:FOLDER_B
解决方案
如果我正确理解您的要求,如何:
#!/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
,该字段在“2018 年 9 月”中以“1809”的每两位数字保存年份和月份,因此我们可以使用它作为键对列表进行排序。
另一个技巧是进程替换来禁止创建临时文件只是为了对列表进行排序。
希望这可以帮助。
如果declare -A
由于 bash 版本而无法工作,这里是 AWK 的替代方案:
#!/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 脚本:
#!/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 版本:
#!/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
推荐阅读
- asp.net-mvc - 接受来自 MVC 控制器的 websocket 升级
- bash - 使用外部实用程序 (plink) 运行 shell 脚本 - 无法提供上下文
- django - 如何在 django urlpatterns 中使用查询字符串重定向?
- node.js - model.find() 在函数中返回空,而在函数外正常工作?
- c# - 如何检查文件哈希是否已使用 C# 更改
- angularjs - 使用角度 5 解析的 css calc() 遇到问题
- linux - 为什么aria2c Linux版比Windows版大很多
- toast - Nuxt.js - 无法解析“@nuxtjs/toast”
- react-native - 尝试在 react-native-modal 中组合 2 个或多个模态
- excel - Excel 根据单元格值定义范围(按列 - A 到 E )