如何将特定的文本文件内容添加到目录及其子目录中的每个文本文件中?

Iva*_*van 6 command-line find text-processing files

我讨厌用许可/归属注释来混淆我的源代码文件,但有时这是必需的。因此,编写了数十个源代码文件(在子目录树中组织),我需要在每个文件的开头添加相同的多行注释。

我怀疑这是使用标准 GNU/Linux 命令行工具完成的一项非常容易的任务,尽管我几乎不擅长认真使用它们,因此请原谅并寻求您的帮助。

我需要的是更换每一个theTargetFile.txt./*.txt(包括子目录递归)喜欢的东西cat theCommonComment.txt theTargetFile.txt

我还希望排除适合特定更具体掩码的文件,例如考虑所有*.txt*.DontTouch.txt保持完整。

我认为我真正需要的最难的部分是一个find基于奇特的咒语,它可以运行在子目录、包含*.txt文件和排除*.DontTouch.txt文件中。

Gra*_*eme 8

最直接的方法,我可以看到这样做是GNU findbashsponge从实用moreutils

find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -print0 |
  while IFS= read -rd '' file; do
    echo 'cat path/to/theCommonComment.txt "$file" | sponge "$file"'
  done
Run Code Online (Sandbox Code Playgroud)

就目前而言,这只会打印cat/sponge命令而不实际执行任何操作。一旦你确定你有你想要的东西,你可以删除命令周围的回声和单引号。

不使用sponge-print0查找选项可能并非在所有系统上都可用:

find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -exec sh '
  for file; do
    tempfile=$(mktemp)
    cat path/to/theCommonComment.txt "$file" >"$tempfile"
    mv "$tempfile" "$file"
  done
  ' sh {} +
Run Code Online (Sandbox Code Playgroud)

没有简单的方法来阻止这个简单的打印它会做什么,所以要小心。需要注意的一件事 - 确保您的theCommonComment.txt文件不在您正在执行递归操作的目录中(或至少确保它被排除在查找之外),否则您最终会得到两个标题一些文件。

更新

最后一个想法是您可能想要检查标题是否已添加到文件中。如果您添加新文件并且必须再次运行该命令,这可能很有用。它还解决了theCommonComment.txt在搜索路径中包含文件的问题。这两个解决方案将变成:

comment_file=path/to/theCommonComment.txt
size=$(wc -c "$comment_file")

find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -print0 |
  while IFS= read -rd '' file; do
    if [ cmp -n "$size" $comment_file" "$file" ]; do
      echo 'cat "$comment_file" "$file" | sponge "$file"'
    fi
  done
Run Code Online (Sandbox Code Playgroud)
export comment_file=path/to/theCommonComment.txt
export size=$(wc -c "$comment_file")

find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -exec sh '
  for file; do
    if [ cmp -n "$size" $comment_file" "$file" ]; do
      tempfile=$(mktemp)
      cat "$comment_file" "$file" >"$tempfile"
      mv "$tempfile" "$file"
    fi
  done
  ' sh {} +
Run Code Online (Sandbox Code Playgroud)


Ram*_*esh 1

我会创建一个文件,其中dummy包含您要替换的内容。所以dummy文件如下所示。

<?php
 /**
  *
  * Copyright (C) MyCompany, Ltd. - All Rights Reserved
  * Unauthorized copying of this file, via any medium is strictly prohibited
  * Proprietary and Confidential
  * 
  *
  */
Run Code Online (Sandbox Code Playgroud)

之后,我将执行以下脚本。

for f in ./*; do
sed -i '/<?php/{
    s/<?php//g
    r dummy
}' $f
done
Run Code Online (Sandbox Code Playgroud)

我将其替换<?php为空格,并将其替换为文件中的内容dummy

当然,您可以修改上面的代码以满足您的要求。

然而,有一种更复杂的方法可以做到这一点。

for f in *; do 
  echo "whatever" > tmpfile
  cat $f >> tmpfile
  mv tmpfile $f
done
Run Code Online (Sandbox Code Playgroud)

上面的答案取自这里。您基本上是先将内容放入 tmpfile,然后将原始内容添加到 tmpfile。完成后,您将 tmpfile 重命名回原始文件名。