如何按创建日期排序将多个文本文件合并为一个文本文件?

如何按创建日期排序将多个文本文件合并为一个文本文件?

我是新手所以请帮忙:

我使用 Scratch 在我的 iPhone 上记日记,将我做的所有笔记输出到存储在 Dropbox 中的单独的 .txt 文件中。

我已经将其与我的 Ubuntu 14.04 系统同步,因此在我的文件中我有一个文件夹,其中存储了所有的文本文件:

/主页/斯图尔特/Dropbox/Scratch

我想要运行一个命令,将所有这些文件连接成一个文件,并附带以下条件:

  1. 按创建日期排序(最早的文件优先)
  2. 在文件内容之前单独一行打印文件日期
  3. 每个文件后都包含一个空白行,后面跟着某种分隔线

因此输出文件包含类似如下的条目:

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

此脚本同时使用创建日期修改日期,比较后取最早的。

来源

  1. 关于创建日期
  2. 其他文件系统中的创建日期
  3. 查找创建日期的脚本

相关内容