如何以编程方式(不使用vi)将DOS/Windows换行符转换为Unix换行符?

dos2unix和unix2dos命令在某些系统上不可用。 如何使用sed、awk和tr等命令模拟它们?


当前回答

我根据接受的答案做了一个脚本,所以你可以直接转换它,而不需要一个额外的文件,然后删除和重命名。

convert-crlf-to-lf() {
    file="$1"
    tr -d '\015' <"$file" >"$file"2
    rm -rf "$file"
    mv "$file"2 "$file"
}

只要确保你有一个像“file1.txt”这样的文件,“file1.txt”。Txt2”不存在,否则将被覆盖。我将此作为存储文件的临时位置。

其他回答

作为Jonathan Leffler的Unix to DOS解决方案的扩展,当你不确定文件当前的行结束符时,可以安全地转换为DOS:

sed '/^M$/! s/$/^M/'

这将在转换为CRLF之前检查该行是否已经在CRLF中结束。

对于Mac OS X,如果您安装了Homebrew (http://brew.sh/):)

brew install dos2unix

for csv in *.csv; do dos2unix -c mac ${csv}; done;

确保您已经复制了文件,因为这个命令将在适当的位置修改文件。 -c mac选项使开关与OS X兼容。

安装dos2unix,然后就地转换文件

dos2unix <filename>

将转换后的文本输出到不同的文件使用

dos2unix -n <input-file> <output-file>

你可以在Ubuntu或Debian上安装它

sudo apt install dos2unix

或者在macOS上使用Homebrew

brew install dos2unix

有趣的是,在Windows上的Git Bash中,sed ""已经做到了:

$ echo -e "abc\r" >tst.txt
$ file tst.txt
tst.txt: ASCII text, with CRLF line terminators
$ sed -i "" tst.txt
$ file tst.txt
tst.txt: ASCII text

我的猜测是,sed在从输入读取行时忽略它们,并且总是将Unix行结束符写入输出。

在Bash 4.2及更新版本中,您可以使用类似这样的方法来剥离后面的CR,它只使用Bash内置:

if [[ "${str: -1}" == $'\r' ]]; then
    str="${str:: -1}"
fi