如何在许多文件末尾添加换行符

Syl*_*ain 1 linux bash shell

我有很多 PHP 文件,我想用 bash 脚本修复最后一行(如果不存在)之后的换行符。

有什么命令可以轻松做到这一点吗?

谢谢 :)

F. *_*uri 6

短而快的

但在每个文件末尾添加换行符。要严格在文件末尾添加换行符(如果没有),请转到此答案的第二部分!

tee是您正在寻找的工具:

简单地:

tee -a <<<'' file1 file2 ...
Run Code Online (Sandbox Code Playgroud)

或者

find /path -type f ! -empty -name '*.php' -exec tee -a <<<'' {} +
Run Code Online (Sandbox Code Playgroud)

警告:不要错过-a选项!

它非常快,但在每个文件上添加换行符。

sed '${/^$/d}' -i file1 file2 ...(您可以像所有文件中的所有空最后行一样输入第二个命令。;)

再次警告:我坚持:如果您错过了命令-a标志tee,这将很快替换换行符找到的每个文件的内容!因此您的所有文件都将变为!)

一些解释:

man tee

NAME
       tee - read from standard input and write to standard output and files

SYNOPSIS
       tee [OPTION]... [FILE]...

DESCRIPTION
       Copy standard input to each FILE, and also to standard output.

       -a, --append
              append to the given FILEs, do not overwrite
Run Code Online (Sandbox Code Playgroud)
  • 因此,tee将复制、附加(由于选项a)到作为参数提交的每个文件,标准输入上的内容。
  • 功能:“ here strings”(请参阅man -Pless\ +/Here.Strings bash​​),您可以使用command <<<"here string""来替换 echo "here string"| command. 为此,bash 在提交的字符串中添加换行符(甚至是空字符串:)<<<''

更慢,但更强

修复最后一行之后的换行符(如果不存在)

由于分叉有限,请保持速度很快,但tail -c1无论如何都必须为每个文件完成一个分叉!

while IFS= read -d '' -r file
do
    IFS= read -d "" chr < <(
        exec tail -c1 "$file"
    )
    if [[ $chr != $'\n' ]]
    then
        echo >> "$file"
    fi   
done < <(
    find . -type f ! -empty -name '*.php' -print0
)
Run Code Online (Sandbox Code Playgroud)

可以写得更紧凑:

while IFS= read -d '' -r file; do
    IFS= read -d "" chr < <( exec tail -c1 "$file" )
    [[ $chr != $'\n' ]] && echo >> "$file"
done < <( find . -type f ! -empty -name '*.php' -print0 )
Run Code Online (Sandbox Code Playgroud)
  • find -print0打印由空字符分隔的每个文件名\0
  • IFS= read -d '' -r file不考虑特殊字符空格,因此$file可以保存任何类型的文件名、包含空格或重音字符的事件。
  • exec告诉 bash 作为子进程执行tail,避免默认的第二个 forktailsubsubprocess.
  • tail -c1读取最后一个字符$file
  • IFS= read -d "" chr将最后一个字符存储到$chr变量中。