![如何按创建日期排序将多个文本文件合并为一个文本文件?](https://linux22.com/image/862746/%E5%A6%82%E4%BD%95%E6%8C%89%E5%88%9B%E5%BB%BA%E6%97%A5%E6%9C%9F%E6%8E%92%E5%BA%8F%E5%B0%86%E5%A4%9A%E4%B8%AA%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E5%90%88%E5%B9%B6%E4%B8%BA%E4%B8%80%E4%B8%AA%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%EF%BC%9F.png)
我是新手所以请帮忙:
我使用 Scratch 在我的 iPhone 上记日记,将我做的所有笔记输出到存储在 Dropbox 中的单独的 .txt 文件中。
我已经将其与我的 Ubuntu 14.04 系统同步,因此在我的文件中我有一个文件夹,其中存储了所有的文本文件:
/主页/斯图尔特/Dropbox/Scratch
我想要运行一个命令,将所有这些文件连接成一个文件,并附带以下条件:
- 按创建日期排序(最早的文件优先)
- 在文件内容之前单独一行打印文件日期
- 每个文件后都包含一个空白行,后面跟着某种分隔线
因此输出文件包含类似如下的条目:
2014 年 12 月 1 日上午 11:01:
以色列的一家咖啡店。外面的标牌上写着:
“咖啡”——9 谢克尔
“请给我一杯咖啡”——8 谢克尔
“早上好,可以给我一杯咖啡吗?”——7 谢克尔--
2014 年 1 月 25 日上午 11:01:
你无法超越自己的自我 - 索尔斯克亚--
等等。我曾经使用过其他可以自动添加的应用程序,但我不知道如何复制它。
我查看了这里的很多帮助文件,但没有发现任何可以帮助我实现我想要的输出的文件。
非常感谢您的帮助!
更多信息
我尝试创建下面建议的脚本并按照步骤操作。但是我得到了以下响应:
stuart@StudioClough:/home$ chmod +x $HOME/my_concat
stuart@StudioClough:/home$ ./my_concat /home/stuart/Dropbox/Scratch > new_concatenated_file
bash:new_concatenated_file:权限被拒绝
我是否必须以某种方式以 sudo 身份运行它?
答案1
这可以用python脚本来完成,附带说明一下:我采用了修改日期而不是创建日期,因为创建日期几乎肯定与真实的创建日期:这是文件复制到计算机的日期,而修改日期在复制过程中似乎没有变化(请参阅@cOrps 回答中的讨论)。您必须看看它是否适合您的情况。
如果您可以接受,您可以使用下面的脚本创建一个包含笔记的合并文件。它会读取笔记、对笔记进行排序并将其附加到文本文件中(如果不存在则创建它)。
好消息是,您可以将新注释附加到同一个文件而不会覆盖旧注释。
示例输出:
Mon Sep 29 08:48:31 2014
This is my first note.
As you can read, I am not really awake yet.
----------
Mon Sep 29 09:04:06 2014
It is really time I am going to eat something.
I am a bit hungry.
Making it a bit longer.
----------
如何使用:
- 将以下脚本复制到一个空文件中,并将其另存为
add_notes.py
- 更改目录
files_dir
(您的笔记所在的位置)和您想要保存笔记的文件:(combined_file
如果文件不存在,脚本将创建该文件) 在终端窗口中输入以下命令来运行脚本:
python3 /path/to/add_notes.py
剧本:
#!/usr/bin/env python3
import os
import time
import subprocess
# --------------------------------------------------------
files_dir = "/path/to/your/textfiles"
combined_file = "/path/to/your/combined/file.txt"
# ---------------------------------------------------------
notes = []
if not os.path.exists(combined_file):
subprocess.Popen(["touch", combined_file])
def read_file(file):
with open(file) as note:
return note.read()
def append_file(combined_file, text):
with open(combined_file, "a") as notes:
notes.write(text)
for root, dirs, files in os.walk(files_dir):
for name in files:
subject = root+"/"+name
cr_date_text = time.ctime(os.path.getmtime(subject))
cr_date_n = os.stat(subject).st_mtime
notes.append((cr_date_n, cr_date_text, subject))
notes.sort(key=lambda x: x[0])
for note in notes:
text = note[1]+"\n"+read_file(note[2])+"\n"+"-"*10+"\n"
append_file(combined_file, text)
答案2
这是一个 bash 解决方案。如果您使用ext4 文件系统. 它使用ext4
存储在crtime
字段中的文件创建日期。
在任意位置创建此脚本。假设my_concat
在您的$HOME
目录中(就您而言是/home/stuart
):
#!/bin/bash
get_crtime() {
for target in "${@}"; do
inode=$(ls -di "${target}" | cut -d ' ' -f 1)
fs=$(df --output=source "${target}" | tail -1)
crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null |
grep -oP 'crtime.*--\s*\K.*')
printf "%s\n" "${crtime}"
done
}
get_epoch_crtime(){
date --date "$(get_crtime $1)" +%s
}
get_epoch_mtime() {
stat -c %Y $1
}
# takes two date as input, returns earlier date
get_earlier_time(){
if [[ "$1" -lt "$2" ]]; then
echo $(date -d @$1 +%m/%d/%Y:%H:%M:%S)
else
echo $(date -d @$2 +%m/%d/%Y:%H:%M:%S)
fi
}
if [ $# != 1 ]; then
echo "Required only one argument - full path to folder"
echo "Usage example:"
echo "$0 /var/log/syslog/"
exit 1
fi
if [ -d "$1" ]; then
cd $1
for file in *
do
echo $(get_earlier_time $(get_epoch_crtime $file) $(get_epoch_mtime $file))
cat $file
echo -e "\n-------"
done
else
echo "The folder specified is not exists ($1). Please enter full path"
fi
使其可执行:
chmod +x $HOME/my_concat
现在转到您的$HOME
文件夹并运行脚本。脚本将询问您的密码,因为脚本使用sudo
:
./my_concat /home/stuart/Dropbox/Scratch > new_concatenated_file
现在new_concatenated_file
使用一些编辑器阅读:
gedit new_concatenated_file
此脚本同时使用创建日期和修改日期,比较后取最早的。