3

我有一组相当大的文件(每个大约 50 兆字节,至少有一百个),但我需要在每个文件上插入一个小标题(大约 2 打行)以进行处理。我希望在 bash 或 python 中编写一个脚本来执行此操作,但我找不到可以让我在文本文件前面插入的恒定时间函数。如果不是固定时间,我认为完成时间会太长。有没有人有这个问题的经验?

4

3 回答 3

4

Similar to Uwe's answer, but if your processing tool can only accept parameters as filenames, you can fake one up with mkfifo(1).

For example, in bash...

echo 'My header' > header.txt
echo 'My content' > content.txt
mkfifo fakefile.txt
cat header.txt content.txt > fakefile.txt &
cat fakefile.txt

...would stream the contents of the two files, rather than creating a new file.

于 2013-05-20T14:45:47.043 回答
3

您不能在恒定时间内将文本插入 Unix 文件,无论是在开头还是中间。另一方面,根据您考虑的处理,您可以完全避免插入的可能性很小。如果您的处理工具能够从管道中读取,它就可以工作。然后你可以做类似的事情

cat headerfile datafile | myprocessingtool

这样数据文件就不会被实际修改。

于 2013-05-20T14:37:47.787 回答
2

我相信这接近于你会做的最好的事情(bash):

MYHEADER=/path/to/the/header
HEADERSIZE=$(stat --format %s "$MYHEADER")

for FILENAME in $FILES; do
    OLDSIZE=$(stat --format %s "$FILENAME")
    cat "$MYHEADER" "$FILENAME" > /tmp/headerize.tmp
    NEWSIZE=$(stat --format %s /tmp/headerize.tmp)
    EXPECTEDSIZE=$(($HEADERSIZE+$OLDSIZE))
    if [ "$NEWSIZE" -eq "$EXPECTEDSIZE" ]; then
      mv /tmp/headerize.tmp "$FILENAME"
    else
      echo "Something odd happened when processing $FILENAME, headerization skipped for this file."
    fi
done

除非你有一个非常可悲的系统或太长的时间标准太高,否则这应该在适当的时间内完成。它包括错误检查。当然,您应该确保标题以换行符结尾,否则最终标题行和第一个文本文件行将合并。

这里唯一剩下的优化是确保临时文件与原始文件写入相同的文件系统;这可能会加速 mv 命令。

一般来说,内容插入很慢。无论是在内存中还是在磁盘上,都是如此。我相信你永远不会找到一个恒定时间的解决方案。但是,您可能实际上不需要一个用于一次性批处理作业。

这是 IMO 可以在 Python 中实现的最快的实现。由于它不会创建临时文件,因此它可能比 bash 版本更快:

MYHEADERPATH=/path/to/the/header
with open(MYHEADERPATH, 'r') as f:
    header = f.read()
for filename in files:
    with open(filename, 'r') as f:
        content = f.read()
    with open(filename, 'w') as f:
        f.write(header + content)

但是,如果您希望它严格安全,则必须以与 bash 脚本相同的方式执行此操作,因此最终速度差异可能很小。

于 2013-05-20T14:17:39.760 回答