Bash 批量更改访问和修改日期,以及来自另一个文件的日期';什么内容?
我正在将旧笔记从基于SQL数据库的笔记应用程序迁移到单独的文本文件。 我已经设法将注释和日期代码导出为单独的文本文件 文件的顺序如下所示:Bash 批量更改访问和修改日期,以及来自另一个文件的日期';什么内容?,bash,macos,date,Bash,Macos,Date,我正在将旧笔记从基于SQL数据库的笔记应用程序迁移到单独的文本文件。 我已经设法将注释和日期代码导出为单独的文本文件 文件的顺序如下所示: $ ls -1 Note0001.txt Note0001-date.txt Note0002.txt Note0002-date.txt Note0003.txt Note0003-date.txt $ cat Note0001-date.txt 388766121.742373 $ cat Note0002-date.txt 274605766.2
$ ls -1
Note0001.txt
Note0001-date.txt
Note0002.txt
Note0002-date.txt
Note0003.txt
Note0003-date.txt
$ cat Note0001-date.txt
388766121.742373
$ cat Note0002-date.txt
274605766.273638
$ cat Note0003-date.txt
384996285.436197
日期文件的内容如下所示:
$ ls -1
Note0001.txt
Note0001-date.txt
Note0002.txt
Note0002-date.txt
Note0003.txt
Note0003-date.txt
$ cat Note0001-date.txt
388766121.742373
$ cat Note0002-date.txt
274605766.273638
$ cat Note0003-date.txt
384996285.436197
日期为自2001-01-01纪元起的秒数。请参阅有关格式的其他问题:
如何将notes文件notennn.txt的访问和修改日期批量更改为相应日期文件notennn-date.txt内容中的日期
如何将日期转换为UTC+1?最好考虑DST(夏令时)。
我正在尝试使用此问题描述的方法转换日期:
但它在bash 3.2.57(macOS)中输出了一条错误消息:
我不熟悉终端中的日期和时间戳。迭代每个文件对,访问时间戳,移动时间戳,以便unix工具能够理解,然后触摸文件。大问题是小问题的总和
# find all files named .txt but not -date.txt
find . -name '*.txt' '!' -name '*-date.txt' |
# remove the .txt suffix
sed 's/\.txt$//' |
{
# the reference point of files content
start=$(date -d "2001-01-01" +%s) # will not work with BSD date
# I guess just precompute the value:
start=978303600
# for each file
while IFS= read -r f; do
# get the timestamp
diff=$(<"$f"-date.txt)
# increment the timestamp to seconds since epoch
ref=$(<<<"scale=6; $start + $diff" bc)
# TODO: use a tool convert the timestamp sinece epoch to BSD touch
# compatible format, ie. to ccyy-mm-ddTHH:MM:SS[.frac][Z]
ref=(TODO "$ref")
# change access and modification times of .txt file
touch -d "@$ref" "$f".txt
done
}
#查找名为.txt的所有文件,但不查找-date.txt
找到-名称“*.txt”!”-名称'*-date.txt'|
#删除.txt后缀
sed's/\.txt$/'|
{
#文件内容的参考点
开始=$(日期-d“2001-01-01”+%s)#不适用于BSD日期
#我想只需预先计算值:
开始=978303600
#对于每个文件
而IFS=read-rf;do
#获取时间戳
diff=$(假设您的操作系统本地时区是您想要的输出,并且您有一个支持的awk
版本,您可以使用
以下脚本。另外:
如果DST夏令时标志为正值,则假定时间为
为夏令时;如果为零,则假定时间为标准时间
时间;如果为负值(默认值),则mktime()尝试确定
夏令时是否在指定时间内有效
文件tst.awk
:
BEGIN {
epoch = mktime("2001 01 01 00 00 00")
}
FNR==1 {
close(out)
out = substr(FILENAME, 1, length(FILENAME)-9) ".txt"
}
{
print strftime("%F %T %Z", epoch+$0) > out
}
BEGIN { epoch = mktime("2001 01 01 00 00 00") }
{ print strftime("%F %T %Z", epoch+$0) }
用法:
awk -f tst.awk *-date.txt
示例
下面是一个脚本示例,没有I/O部分,只是转换日期时间
测试文件:
> cat file
388766121.742373
274605766.273638
384996285.436197
脚本tst.awk
:
BEGIN {
epoch = mktime("2001 01 01 00 00 00")
}
FNR==1 {
close(out)
out = substr(FILENAME, 1, length(FILENAME)-9) ".txt"
}
{
print strftime("%F %T %Z", epoch+$0) > out
}
BEGIN { epoch = mktime("2001 01 01 00 00 00") }
{ print strftime("%F %T %Z", epoch+$0) }
输出:
> awk -f tst.awk file
2013-04-27 15:35:21 EEST
2009-09-14 08:22:46 EEST
2013-03-14 23:24:45 EET
默认情况下使用“我的盒子”的时区(EET)。如果我们想打印到不同的时区,我们应该定义该时区并设置TZ
。此外,默认情况下使用DST,请注意,某些天打印为EEST(夏季).你想要这些文件。那是什么日期格式?
你刚才指定了日期是从2001-01-01纪元开始的秒数,所以它们是从纪元开始的秒数。它们是什么格式?如何转换?
那句话中的“it”是什么,转换成什么?转换一个“日期格式”是的,对不起,我编辑了。您的方框是UTC+1时区吗?date+%Z
=?是我的时区UTC+1(瑞典)夏季使用DST。date+%Z给出了CEST。感谢KamilCuk。该脚本是否也尊重UTC+1和DST?我测试了该脚本,它显示了一个错误:touch:unligal option--d该脚本是否也尊重UTC+1和DST?
不知道,请参见人工日期
,了解LC.*
和TZ
环境变量的处理。touch:非法选项--d
och好吧,你在macos上。所以你有openbsd,我在写这篇文章时考虑了GNU工具。你可以安装GNU替代品,或者将脚本重构为BSD touch和date可以使用的东西。如果你在macos上使用自制软件,你可以运行brew安装coreutils
,这将为你提供GNUdate
和touch
作为gdate
和gtouch
。太棒了!谢谢Mark。我在KamilCuk的脚本的第一个版本中更改为gdate和gtouch,它在macOS上工作。但我仍然不知道如何处理UTC+1和DST。这里有一些信息:,但可能有更好的方法。现在真的结束了。谢谢你的回复。我测试并得到以下结果:$awk-f epoch-2001-convert.awk*-date.txt awk:can't open file epoch-2001-convert.awk source line number 1源文件epoch-2001-convert.awk context is>>如何打印DST标志?@Kasam我已经用一个示例进行了更新,以说明我所说的内容,并且默认情况下DST处于打开状态。如果您遇到任何类似的错误>awk:无法打开文件…
这由您来解决,错误消息非常清楚。问题是在macOS上的awk,安装brew gawk后,脚本工作正常。在名为MemoLite0142.txt的文件上运行第一个脚本时,它创建了一个名为MemoLit.txt的文件,并带有时间戳。时间戳的日期错误,但正确[!]时间根据DST进行了调整。修改后的脚本打印到屏幕上。结果与上面相同,日期错误,但时间正确。如何使用此方法更改文件时间戳[具有正确的日期]?@Kasam所有转换的结果和预期日期之间是否存在标准偏移量差异?有多少天?