在 Shell 中将最近 07 天的文件合并为一个文件
concat last 07 days files into one file in Shell
我每天都会生成名称类似于 ABC_20170622.csv
的文件,只有日期参数会被更改。我需要根据日期参数将最近 07 天的文件合并到一个文件中,这将在每个星期一完成。
示例文件集;
Jun 15 07:00 ABC_20170614.csv
Jun 16 07:00 ABC_20170615.csv
Jun 17 07:00 ABC_20170616.csv
Jun 18 07:00 ABC_20170617.csv
Jun 19 07:00 ABC_20170618.csv
Jun 20 07:00 ABC_20170619.csv
Jun 21 07:00 ABC_20170620.csv
Jun 22 07:00 ABC_20170621.csv
Jun 23 07:00 ABC_20170622.csv
就像
cat ABC_20170619.csv ABC_20170620.csv ABC_20170621.csv > one_week.csv
但我需要自动获取日期,这将是 shell 脚本中的 运行..
首先——简单是使用文件时间戳,而不是名称。看起来像:
find . -mtime -7 -exec cat -- {} + >one_week.csv
但假设您确实确实需要使用名称。好的,那么:
#!/usr/bin/env bash
die() { echo "$*" >&2; exit 1; }
[ -n "$BASH_VERSION" ] || die "This script requires bash"
[[ $BASH_VERSION =~ ^[0123] ]] && die "This script requires bash 4.2"
[[ $BASH_VERSION =~ ^4[.][01][.] ]] && die "This script requires bash 4.2"
# bash 4.2: get current epoch time in seconds
printf -v current_time_seconds '%(%s)T' -1
# subtract 7 days from that
prev_week_seconds=$(( current_time_seconds - (60 * 60 * 24 * 7) ))
# convert it to YYYYMMDD
printf -v prev_week_date '%(%Y%m%d)T' "$prev_week_seconds"
# generate the first name that matches
start_file=ABC_${prev_week_date}.csv
# generate an array listing files that exist with that name or newer
files=( )
for f in ABC_*.csv; do
if [[ $f = $start_file || $f > $start_file ]]; then
files+=( "$f" )
fi
done
# concatenate all files generated above
cat -- "${files[@]}" >one_week.csv
如果您需要使用旧版本的 bash(错误,合理地 旧版本的 bash -- 我不保证3.2 之前的任何内容),将 printf -v current_time_seconds '%(%s)T' -1
更改为 current_time_seconds=$(date +%s)
,并将 printf -v prev_week_date '%(%Y%m%d)T' "$prev_week_seconds"
更改为 prev_week_date=$(date -d "@$prev_week_seconds" +%Y%m%d)
。请注意,即使这些也需要 GNU 日期,并且不能保证与其他 OS 供应商提供的 date
命令一起使用。
我每天都会生成名称类似于 ABC_20170622.csv
的文件,只有日期参数会被更改。我需要根据日期参数将最近 07 天的文件合并到一个文件中,这将在每个星期一完成。
示例文件集;
Jun 15 07:00 ABC_20170614.csv
Jun 16 07:00 ABC_20170615.csv
Jun 17 07:00 ABC_20170616.csv
Jun 18 07:00 ABC_20170617.csv
Jun 19 07:00 ABC_20170618.csv
Jun 20 07:00 ABC_20170619.csv
Jun 21 07:00 ABC_20170620.csv
Jun 22 07:00 ABC_20170621.csv
Jun 23 07:00 ABC_20170622.csv
就像
cat ABC_20170619.csv ABC_20170620.csv ABC_20170621.csv > one_week.csv
但我需要自动获取日期,这将是 shell 脚本中的 运行..
首先——简单是使用文件时间戳,而不是名称。看起来像:
find . -mtime -7 -exec cat -- {} + >one_week.csv
但假设您确实确实需要使用名称。好的,那么:
#!/usr/bin/env bash
die() { echo "$*" >&2; exit 1; }
[ -n "$BASH_VERSION" ] || die "This script requires bash"
[[ $BASH_VERSION =~ ^[0123] ]] && die "This script requires bash 4.2"
[[ $BASH_VERSION =~ ^4[.][01][.] ]] && die "This script requires bash 4.2"
# bash 4.2: get current epoch time in seconds
printf -v current_time_seconds '%(%s)T' -1
# subtract 7 days from that
prev_week_seconds=$(( current_time_seconds - (60 * 60 * 24 * 7) ))
# convert it to YYYYMMDD
printf -v prev_week_date '%(%Y%m%d)T' "$prev_week_seconds"
# generate the first name that matches
start_file=ABC_${prev_week_date}.csv
# generate an array listing files that exist with that name or newer
files=( )
for f in ABC_*.csv; do
if [[ $f = $start_file || $f > $start_file ]]; then
files+=( "$f" )
fi
done
# concatenate all files generated above
cat -- "${files[@]}" >one_week.csv
如果您需要使用旧版本的 bash(错误,合理地 旧版本的 bash -- 我不保证3.2 之前的任何内容),将 printf -v current_time_seconds '%(%s)T' -1
更改为 current_time_seconds=$(date +%s)
,并将 printf -v prev_week_date '%(%Y%m%d)T' "$prev_week_seconds"
更改为 prev_week_date=$(date -d "@$prev_week_seconds" +%Y%m%d)
。请注意,即使这些也需要 GNU 日期,并且不能保证与其他 OS 供应商提供的 date
命令一起使用。