我如何使用fileinput编辑多个文件?

时间:2017-04-27 10:46:54

标签: python python-2.7 file

我在python 2.7中使用os.walk打开多个文件,然后将这些文件的所有感兴趣行添加到列表中。后来我想用fileinput编辑那些行并关闭它。我怎样才能做到这一点?使用下面的代码是我打开文件的方式:

import os
import fnmatch
import fileinput

lines = []

def openFiles():
    for root, dirs, files in os.walk('/home/test1/'):
        for lists in fnmatch.filter(files, "*.txt"):
            filepath = os.path.join(root, lists)
            print filepath
            with open(filepath, "r") as sources:#opens 8 files and read their lines
                #edit = fileinput.input(filepath, inplace=1)
                for line in sources:
                    if line.startswith('xe') :
                      lines.append(line)

然后,对于以xe开头的每一行,我想在它前面添加一个#然后关闭该文件。我想在不同的功能中这样做。

2 个答案:

答案 0 :(得分:1)

以下是我的方式,添加到您的代码中:

export TMPDIR=/Users/yourpath/SourceCode/FFmpeg/tmpdir
NDK=/Users/yourpath/Android/android-ndk-r10d
SYSROOT=$NDK/platforms/android-16/arch-arm/
TOOLCHAIN=/Users/yourpath/Android/android-ndk-r10d/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64

CPU=arm
PREFIX=/Users/liuchao/SourceCode/FFmpeg/ffmpeg_install/
#ADDI_CFLAGS="-marm"
ADDI_CFLAGS="-mfpu=neon -mfloat-abi=softfp"

function build_one
{
./configure \
--prefix=$PREFIX \
--target-os=linux \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
--disable-shared \
--enable-static \
--disable-asm \
--disable-yasm \
--enable-gpl \
--enable-stripping \
--enable-runtime-cpudetect \
--enable-cross-compile \
--enable-version3 \
--enable-nonfree
--enable-libx265 \
--enable-w32threads \
--enable-hwaccels \
--enable-neon \
--enable-decoders \
--enable-devices \
--enable-encoders \
--enable-muxers \
--enable-encoder=rawvideo \
--enable-protocols \
--enable-protocol=file \
--enable-avfilter \
--enable-network \
--enable-avdevice \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG

import os import fnmatch import fileinput def openFiles(dir): filePaths = [] for root, dirs, files in os.walk(dir): for textFile in fnmatch.filter(files, "*.txt"): filepath = os.path.join(root, textFile) filePaths.append(filepath) return filePaths def prefixLines(filepaths, chartoPrefix, prefixWith): res = '' for filepath in filepaths: # Read file with open(filepath, 'r') as f: for line in f: if line.startswith(chartoPrefix): res += prefixWith + line else: res += line # Write to file with open(filepath, 'w') as f: f.write(res) res = '' # Rest res prefixLines(openFiles(r'/home/test1/'), 'xe', '#') 有许多缺点:

  • 因为我们阅读了所有文件行并将它们存储在prefixLines中,所以我们 对于大文件可能内存不足。

  • 如果某个程序员忘了缩进res 右侧阻止或如果完全省略res = ''并且代码仍然运行 用户需要的实际文件,你最终会写出内容 先前读取的文件到下一个文件和最后一个文件 文件将具有所有读取文件的内容。这就是你的原因 在测试环境中使用此代码或谨慎使用它。

此代码仅用于演示如何实现所需的效果,为带有另一个字符串的字符串开头的文件行添加前缀。因此,建议稍微改进此代码。例如,不是读取文件的所有内容并将它们存储在res,您只需保存需要加前缀的行号,从而无需将所有数据加载到内存中。 res也可以帮助返回文件号,它在2.7中返回一个iterable。通过避免enumerate我们不仅可以节省记忆,还可以消除子弹2中的缺点。

答案 1 :(得分:0)

我最终这样做了。但是我在主代码中使用了类,所以它分为2个函数而不是1个。在我的主代码中,我使用一个列表来保存所有文件路径,并使用fileinput以这种方式从列表中打开每个文件路径for line in fileinput.FileInput(pathlist, inplace=1): do something.我感谢@direprobs的答案,因为她阐明了我的方式我应该这样做。

import fnmatch
import fileinput
import os
import sys

def openFiles():
    for dirpath, dirs, files in os.walk('/home/test1/'):
        for filename in fnmatch.filter(files, "*.txt"):
            filepaths = os.path.join(dirpath, filename)
            for line in fileinput.FileInput(filepaths, inplace=1):
                if line.startswith("xe"):
                    add = "# {}".format(line)
                    line = line.replace(line, add)
                sys.stdout.write(line)
                fileinput.close()


openFiles()