如何在 Unix 和 Windows 换行符格式之间批量转换文件系统分支中的所有文件?

如何在 Unix 和 Windows 换行符格式之间批量转换文件系统分支中的所有文件?

大家都知道 :-) 在 Windows 纯文本文件中行以 CR+LF 终止,而在 Unix&Linux 中仅以 LF 终止。如何快速将所有源代码文件从一种格式转换为另一种格式并转换回来?

答案1

这取决于:如果文件受到版本控制,这可能是一个相当不受欢迎的历史污染决定。 Git 可以选择在签出时自动转换行结尾。

如果您不在乎并希望快速转换,可以使用fromdos/todosdos2unix/等程序unix2dos来为您完成此操作。您可以使用findfind . -type f -name '*.php' -exec dos2unix '{}' +

答案2

有几个专门的程序,包括

只需选择适当方向的工具并在命令行上传递要转换的文件名称即可。


如果您两者都没有,但有 Linux 或 Cygwin:

sed -i -e 's/\r\+$//' filename             # dos|unix -> unix
sed -i -e 's/\r*$/\r/' filename            # dos|unix -> dos

如果你有 perl:

perl -i -pe 's/\r+$//' filename            # dos|unix -> unix
perl -i -pe 's/\r*$/\r/' filename          # dos|unix -> dos

仅使用 POSIX 工具(包括 BusyBox),要从 unix 转到 dos,您需要在 sed 命令中逐字传递 CR 字符。

cr=$(echo | tr '\n' '\r')
sed -e "s/$cr*\$/$cr/" <filename >filename.dos
mv filename.dos filename

另一方面,您可以简单地删除所有 CR:

tr -d '\r' <filename >filename.dos
mv filename.dos filename

您可以使用通配符一次转换同一目录中的多个文件,例如

sed -i -e 's/\r\+$//' *.txt

要转换当前目录及其子目录中的所有文件,如果您的 shell 是 zsh,您可以使用**/,例如

sed -i -e 's/\r\+$//' **/*.txt

您可以**/在 bash ≥4 中使用,但您需要shopt -s globstar先运行(您可以将此行放在您的 中~/.bashrc)。您可以**/在 ksh93 中使用,但您需要set -o globstar先运行(您可以将此行放在您的~/.kshrc.

如果只能使用需要重定向的工具,请使用循环for

for x in *.txt; do
  tr -d '\r' <"$x" >"$x.dos"
  mv -- "$x.dos" "$x"
done

如果您没有**/或需要更复杂的匹配来选择要转换的文件,请使用该find命令。这是一个 Linux/Cygwin 示例,它递归地转换当前目录及其子目录下的所有文件,除了名为 的文件.o和名为 的子目录下的文件bin

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sed -i -e 's/\r\+$//' {} +

这是一个 POSIX 示例。我们告诉find启动一个可以执行必要重定向的 shell。

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sh -c '
       tr -d '\r' <"$0" >"$0.dos"
       mv -- "$0.dos" "$0"
' {} \;

find通过在 shell 命令中使用循环,您可以使该方法稍微快一些,但代价是代码更复杂。

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sh -c '
       for x; do
         tr -d '\r' <"$x" >"$x.dos"
         mv -- "$x.dos" "$x"
       done
' _ {} +

答案3

温斯普也会自动转换,如果这么说的

如果您的文件全部位于同一目录中:

DIRECTORY=/your/directory
unix2dos $DIRECTORY/*

答案4

更改自ASCII 文本,带有 CRLF 行终止符ASCII 文本

VIM - Vi IMproved 8.0(2016年9月12日,2018年4月10日21:31:58编译)


当前目录下的所有文件

for i in *; do vi -c "set fileformat=unix | wq" "${i}"; done

特定掩码(当前目录中以“文件​​”一词开头的所有文件名)

for i in file*; do vi -c "set fileformat=unix | wq" "${i}"; done

另一个掩码(当前目录中包含单词“file”的所有文件名)

for i in *file*; do vi -c "set fileformat=unix | wq" "${i}"; done

要将文件转换回 CRLF,只需将 fileformat=unix 更改为 fileformat=dos:

for i in *file*; do vi -c "set fileformat=dos | wq" "${i}"; done

这是使用 vim 转换文件格式最快的方法。


或者,也可以使用 sed 通过按 CTRL+V 然后按 CTRL+M 来删除所有 ^M

for i in *; do sed -i s/^M// "$i"; done

或者

for i in *; do sed -i s/^M// "${i}"; done

这也会将当前目录中的所有 CRLF 文件更改为 ASCII 文本。

相关内容