UNIX中基于文件内容的文件重命名
我在文件中有日期和文件名。 两者都有一些价值,如下所示 我的要求是,我应该像FILENAME\u QUARTERDATE那样重命名文件 我的文件(myfile.txt)如下所示:UNIX中基于文件内容的文件重命名,unix,awk,file-rename,batch-rename,Unix,Awk,File Rename,Batch Rename,我在文件中有日期和文件名。 两者都有一些价值,如下所示 我的要求是,我应该像FILENAME\u QUARTERDATE那样重命名文件 我的文件(myfile.txt)如下所示: QUARTERDATE: 03/31/14 - 06/29/14 FILENAME : LEAD field1 field2 34567 20.0 5,678 20.0 5,678 20.0 5,678 20.0 5,678 20.0 5,
QUARTERDATE: 03/31/14 - 06/29/14
FILENAME : LEAD
field1 field2
34567
20.0 5,678
20.0 5,678
20.0 5,678
20.0 5,678
20.0 5,678
我希望文件名为LEAD_201402.txt
文件中的日期范围是第二季度,所以我给出的是201402
提前感谢您的回复。季度是如何定义的?
newname=$(awk '/QUARTERDATE/ { split($4, d, "/");
quarter=sprintf("%04d%02d", 2000+d[3], int((d[1]-1)/3)+1); }
/FILENAME/ { fn = $3; print fn "_" quarter; exit; }' "$file")
mv "$file" "$newname"
正如在对主要问题的评论中所指出的那样,这一问题尚未明确界定
上一季度的季度日期行中会显示哪些数据?第一季度会以前一年的12月开始吗?第二季度的结束日期可能是7月(或4月的第一季度,或10月的第三季度,或1月的第四季度)?由于第二季度的第一个日期是3月,因此需要了解这些替代方案。一个季度是否可以同时早开始晚结束(14周的一个季度) 答复如下:
第二季度的季度日期将从4月的第一个星期一开始,到6月的最后一个星期日结束 触发了一个反响应:
2014年03月31日是星期一,但几乎不是四月的星期一。这主要意味着你对季度的定义还不清楚。例如,明年,2015-03-30是星期一,但“四月的第一个星期一”是2015-04-06。2015年3月的最后一个星期日是2015年3月29日。那么2015年3月30日星期一到2015年4月05日星期日属于哪个季度,为什么?如果您不知道(如何和为什么),我们无法可靠地帮助您 似是而非的工作假说
- Y2K的教训已经被遗忘了(该死,为什么今年还要用两位数呢!)
- 四分之一的时间为整周
- 季度从周一开始,周日结束
- 季度与日历季度保持一致,而不是在一年中四处漂流。(91天中有13周,一年中有4个这样的季度,但在普通年份中有一个额外的一天,在闰年中有两个额外的一天,这意味着偶尔你会有14周的季度,以确保事情保持一致。)
- 季度中第一个日期的日期将接近1月1日、4月1日、7月1日或10月1日,但月份可能是12月、3月(如问题所述)、6月或9月
- 季度中最后一个日期的日期将接近3月31日、6月30日、9月30日、12月31日,但月份可能是4月、7月、10月或1月
- 通过将1模12(范围为1..12的值,而不是0..11)添加到起始月,您应该在日历季度中以一个月结束
- 通过减去1模12(值再次在1..12范围内)到月底,您应该在日历季度结束一个月
- 如果数据有效,“开始+1”和“结束-1”月份应在同一季度
- 如果开始日期是12月(但这表明是下一年的第一季度),那么年初可能会减少1
- 如果结束日期为1月,则结束年份可能会缩短一个月(但这表示上一年的第四季度)
#!/bin/sh
awk '/QUARTERDATE/ {
split($2, b, "/")
split($4, e, "/")
if (b[1] == 12) { q = 1; y = e[3] }
else if (e[1] == 1) { q = 4; y = b[3] }
else
{
if (b[3] != e[3]) {
print "Year mismatch (" $2 " vs " $4 ") in file " FILENAME
exit 1
}
m = int((b[1] + e[1]) / 2)
q = int((m - 1) / 3) + 1
y = e[3]
}
quarter = sprintf("%.4d%.2d", y + 2000, q)
}
/FILENAME/ {
print $3 "_" quarter
# exit
}' "$@"
m
的计算将开始月份加1与结束月份减1相加,然后将整数除以2。对于已经处理过的极端情况,这总是会产生一个正确季度的月数
与文件名关联的退出
前面的注释允许更轻松地进行测试。当分别处理每个文件时,如Barmar的示例中所示,exit
是一个重要的优化。请注意,如果输入来自标准输入,则错误消息会给出一个空文件名。(顺便说一句,我不知道如何将错误消息打印到标准错误而不是标准输出,而不是通过平台特定的技术,例如打印“message”>“/dev/stderr”
或打印“message”>“/dev/fd/2”
)
给出该样本输入数据(从2014年第一季度到2015年第二季度的6个季度的半合理开始和结束日期):
此脚本的输出为:
LEAD_201401
LEAD_201402
LEAD_201403
LEAD_201404
LEAD_201501
LEAD_201502
您可以在合理的范围内调整季度的开始和结束日期,您仍然可以获得所需的输出。但要时刻警惕历法计算;它们几乎总是比你预期的更难。上一季度的季度日期行中会出现什么数据?第一季度会以前一年的12月开始吗?第二季度的结束日期可能是7月(或4月的第一季度,或10月的第三季度,或1月的第四季度)?由于第二季度的第一个日期是3月,因此需要了解这些替代方案。一个季度能否同时早开始晚结束(14周的季度)?第二季度的季度日期将从4月的第一个星期一开始,到6月的最后一个星期日结束。2014-03-31是星期一,但几乎不是4月的星期一。这主要意味着你对季度的定义还不清楚。例如,明年,2015-03-30是星期一,但“四月的第一个星期一”是2015-04-06。2015年3月的最后一个星期日是2015年3月29日。那么2015年3月30日星期一到2015年4月05日星期日属于哪个季度,为什么?如果你不知道,我们无法可靠地帮助你。我会让事情变得简单。。。。将假定2014年第2季度。。。。季度开始日期肯定不会超过本月1日(即4月1日)。1日应为星期一,或从4月1日开始的第一个星期一,如3月31日、30日、29日……等等,均应为星期一。本季度的同一截止日期也不得超过6月31日。。。31日应为星期日或31日之前的某一天,即6月31日星期日;必须换一个新的c
LEAD_201401
LEAD_201402
LEAD_201403
LEAD_201404
LEAD_201501
LEAD_201502