如何在终端中递归地将包含文件名的文本行添加到所有文本文件中?

时间:2016-08-19 15:20:01

标签: bash macos shell sed terminal

我有一堆javascript文件,我需要在包含文件名的每个文件开头的新行添加注释,例如。

/* app.js */

我希望以递归方式从我终端上的终端上的文件夹中执行此操作。

有人可以帮忙吗?

谢谢!

3 个答案:

答案 0 :(得分:0)

首先,我们必须找到这些文件:

$ find $folder_name -type f -name "*.js" -print

这将找到后缀为*.js的所有文件。 type -f表示只查找文件(只是因为您的目录名以.js结尾)。我将假设您的JavaScript文件名不包含空格,或控制名称中的<NL>个字符等字符。否则,我们将不得不做更多的工作。

我们可以使用find语句找到所有这些文件,然后我们可以使用这些文件。一旦我们找到这些文件,我们就必须弄清楚如何使用该文件来获取注释行。

我们采取三步走法:

  1. 首先,我们将在其中创建一个带有注释行的新文件。
  2. 接下来,我们将新文件末尾的旧文件连接起来。
  3. 我们会将新文件重命名为旧文件。
  4. 首先,我们将使用echo创建一个旧名称的新文件。然后,我们将使用cat命令连接新文件上的旧文件。最后,我们会使用mv 新构建的文件重命名为旧名称。

    find $javascript_dir -type f -name "*.js" -print | while read file_name
    do
        basename=$(basename $file_name)
        echo "/* $basename */" > "$basename.tmp"
        cat "$file_name" >> "$basename.tmp"
        mv "$basename.tmp" "$file_name"
    done
    

    请注意,>会将命令的输出重定向到指定的文件,并且>>会将命令的输出附加到指定的文件。 mv代表 move 。在Unix中,文件实际上是由inode标识存储的。有一个目录,它将inode与文件的全名(包括目录)相匹配。因此,在Unix中移动文件与简单地重命名文件相同,因此更改了目录名称。在Windows批处理中,有单独的moverename命令。在Unix中,他们都是mv

    加成

    我们可以使用sed来预备行:

    find . -name "*.js" -print | while read file_name
    do
        basename=$(basename $file_name)
        sed -i "" "1i\\
        /* $basename */
        " "$file_name"
    done
    

    sed是一个功能强大的行编辑器,大多数人只使用其替换命令模式。但是,sed脚本可能更复杂和丰富(并且模糊不清,这就是您很少看到它们的原因)。

答案 1 :(得分:0)

您可以使用cat -和临时文件:

# adds filename to top of each file in $DIR
DIR=. # set to whatever directory
FILES=$(find $DIR -type f)
for FILE in $FILES; do 
  FILE=$(echo $FILE | sed -e s/\.\\\///) # remove leading "./" if DIR is "."
  echo "/* $FILE */" | cat - $FILE > tempfile.tmp # add the line using a temp file
  mv tempfile.tmp $FILE # move the temp file back to the original file
done

请注意,如果DIR不是,则会添加相对于DIR的文件的完整路径。&#39;。要仅添加文件名本身,您可以使用:

  echo "/* $(basename $FILE) */" | cat - $FILE > tempfile.tmp # add the line using a temp file

答案 2 :(得分:-1)

你可以使用sed,尝试这样的事情:

#!/bin/bash

for i in $(find ./ -name *.js);
do
 `sed -i 's/$i \*\//$i \*\/\n&/' "$i"`
done

使用sed插入换行符可能会出现问题,因为并非所有版本的工作都相同。要概述,请参阅此reference。例如,您可以使用G{G;}替换替换部分。这取决于你的sed版本。 已回答类似问题herehere

另一个有趣的解决方案:

如果您想在第一行后添加换行符,也可以使用:

sed -i "1a\ " test.js

所以将上面的脚本改为:

#!/bin/bash

for i in $(find ./ -name *.js);
do
 `sed -i "1a\ " $1`
done