【问题标题】:Add line on top of each Python file in current and sub directories在当前和子目录中的每个 Python 文件顶部添加行
【发布时间】:2011-10-25 18:30:34
【问题描述】:

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

【问题讨论】:

    标签: python linux perl shell


    【解决方案1】:
    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 中插入文件的开头或结尾。只能重写或追加。

    【讨论】:

      【解决方案2】:
      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)
      

      【讨论】:

      • 您以最短、最明显的方式获得奖励。您确实存在目录或文件名中有空格的潜在错误,但这很容易通过左侧的-print0 和右侧的-0 修复。
      • @tchrist:它不会只是打印 STDOUT 的答案而不是在每个文件的顶部添加行吗?
      • @David,不,sed 的-i 选项意味着就地更新文件。你不会在标准输出上看到任何东西。
      【解决方案3】:

      使用 Perl、Python 或 shell 脚本最简单的方法是什么?

      我会使用 Perl,但那是因为我对 Perl 的了解远胜于对 Python 的了解。哎呀,也许我会在 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
      

      【讨论】:

      • +1 用于使用正确的工具,sed,但你有一个错误:你应该说-print0find 和管道到while IFS= read -d '\0' -r file,以避免出现问题文件的问题名字。
      • 实际上,名称中的空格或制表符在这里不是什么大问题(尽管文件名中间的 LF 是)。查看我的程序,最大的问题是我没有引用变量$file。如果文件名中有空格,我的程序将无法运行。
      【解决方案4】:
      for a in `find . -name '*.py'` ; do cp "$a" "$a.cp" ; echo "Added line" > "$a" ; cat "$a.cp" >> "$a" ; rm "$a.cp" ; done
      

      【讨论】:

      • 最后你可能想rm $a.cp
      • @Didier:你的意思是find . -name *.py
      • @eugene y:感谢您的更正。我还引用了 find 的名称。
      【解决方案5】:

      这会

      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)
      

      【讨论】:

        【解决方案6】:
            #!/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

        【讨论】:

        • 我更喜欢perl -pi -e 'BEGIN { print "A new line" }' $(find . -name '*.py') :)
        • @hobbs:我明白了,但它似乎对我不起作用(在 5.10 上)
        猜你喜欢
        • 2013-02-04
        • 1970-01-01
        • 1970-01-01
        • 2020-11-10
        • 1970-01-01
        • 2021-10-15
        • 1970-01-01
        • 2017-01-07
        • 2011-04-08
        相关资源
        最近更新 更多