在当前目录和子目录中的每个Python文件顶部添加一行

7

我在一个Ubuntu平台上,有一个包含许多.py文件和子目录(也包含.py文件)的目录。我想在每个.py文件的顶部添加一行文字。使用Perl、Python或shell脚本,最简单的方法是什么?

6个回答

6
find . -name \*.py | xargs sed -i '1a Line of text here'

编辑:根据tchrist的评论,处理带有空格的文件名。

假设您已经拥有GNU find和xargs(由于您在问题中指定了linux标签)。

find . -name \*.py -print0 | xargs -0 sed -i '1a Line of text here'

没有GNU工具,你会做如下操作:

while IFS= read -r filename; do
  { echo "new line"; cat "$filename"; } > tmpfile && mv tmpfile "$filename"
done < <(find . -name \*.py -print)

1
你因为采用最短和最明显的方法而获得了奖励。但是,你可能会在目录或文件名中遇到空格的潜在错误,但这很容易通过在左侧使用“-print0”和在右侧使用“-0”来解决。 - tchrist
@tchrist:它不仅会将答案打印到STDOUT,而且还会将该行添加到每个文件的顶部吗? - David W.
@DavidпәЊдёҚпәЊsedзљ„-iйЂ‰йҰ№ж„Џе‘ізқЂеҺџењ°ж›ө新文件。дҢ ењЁstdoutдёЉзњ‹дёҚе€°д»»дҢ•дёњиӨүгЂ‚ - glenn jackman

5
for a in `find . -name '*.py'` ; do cp "$a" "$a.cp" ; echo "Added line" > "$a" ; cat "$a.cp" >> "$a" ; rm "$a.cp" ; done

3
最后,您可能想要执行“rm $a.cp”的操作。 - eumiro
1
@Didier:你是不是指的是 find . -name *.py 呢? - Eugene Yarmash
@eugene y:感谢您的更正。我还引用了find的名称。 - Didier Trosset

4
import os
for root, dirs, files in os.walk(directory):
    for file in files:
        if file.endswith('.py')
            file_ptr = open(file, 'r')
            old_content = file_ptr.read()
            file_ptr = open(file, 'w')
            file_ptr.write(your_new_line)
            file_ptr.write(old_content)

据我所知,在Python中无法在文件开头或结尾插入内容,只能重新写入或追加。

4
    #!/usr/bin/perl

    use Tie::File;
    for (@ARGV) {
        tie my @array, 'Tie::File', $_ or die $!; 
        unshift @array, "A new line";        
    }

要递归处理目录中的所有.py文件,请在您的shell中运行以下命令:

find . -name '*.py' | xargs perl script.pl


1
我有点偏爱 perl -pi -e 'BEGIN { print "A new line" }' $(find . -name '*.py') :) - hobbs
@hobbs:我明白你的想法,但对我来说似乎不起作用(在5.10上)。 - Eugene Yarmash

4

这将

  1. 递归地遍历以当前工作目录为起点的所有目录
  2. 仅修改文件名以“.py”结尾的文件
  3. 保留文件权限(与open(filename,'w')不同)

fileinput还提供了在修改文件之前备份原始文件的选项。


import fileinput
import os
import sys

for root, dirs, files in os.walk('.'):
    for line in fileinput.input(
            (os.path.join(root,name) for name in files if name.endswith('.py')),
            inplace=True,
            # backup='.bak' # uncomment this if you want backups
            ):
        if fileinput.isfirstline():
            sys.stdout.write('Add line\n{l}'.format(l=line))
        else:
            sys.stdout.write(line)

1
使用Perl、Python或shell脚本,最简单的方法是什么?
我会使用Perl,因为我比了解Python更熟悉Perl。但是,也许我会选择Python来更好地学习它。
最简单的方法是使用你熟悉和能够使用的语言。这也可能是最好的方法。
如果这些都是Python脚本,我想你应该知道Python或者有一群知道Python的人可以帮忙。所以,最好还是用Python完成项目。
然而,使用shell脚本也是可能的,如果你最擅长shell,那就随便你了。这是我脑海中想到的一个小的、完全未经测试的shell脚本:
find . -type f -name "*.py" | while read file
do
    sed 'i\
I want to insert this line
' $file > $file.temp
  mv $file.temp $file
done

使用正确的工具sed是正确的,但你有一个bug:你应该使用-print0来告诉find命令,并通过管道传递给while IFS= read -d '\0' -r file,以避免出现文件名问题。 - sorpigal
实际上,名称中的空格或制表符并不是什么问题(尽管文件名中间的LF是个问题)。回顾我的程序,最大的问题是我没有引用变量$file。如果文件名中有空格,我的程序将无法正常工作。 - David W.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接