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

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


当前回答

一个更简单的没有程序的AWK解决方案:

awk -v ORS='\r\n' '1' unix.txt > dos.txt

从技术上讲,“1”是您的程序,因为AWK在给定选项时需要一个。

或者,内部解决方案是:

while IFS= read -r line;
do printf '%s\n' "${line%$'\r'}";
done < dos.txt > unix.txt

其他回答

你可以使用AWK。将记录分隔符(RS)设置为匹配所有可能的换行符的正则表达式。并将输出记录分隔符(ORS)设置为unix样式的换行符。

awk 'BEGIN{RS="\r|\n|\r\n|\n\r";ORS="\n"}{print}' windows_or_macos.txt > unix.txt

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

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

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

dos2unix <filename>

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

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

你可以在Ubuntu或Debian上安装它

sudo apt install dos2unix

或者在macOS上使用Homebrew

brew install dos2unix

这对我很有效

tr "\r" "\n" < sampledata.csv > sampledata2.csv 

The solutions posted so far only deal with part of the problem, converting DOS/Windows' CRLF into Unix's LF; the part they're missing is that DOS use CRLF as a line separator, while Unix uses LF as a line terminator. The difference is that a DOS file (usually) won't have anything after the last line in the file, while Unix will. To do the conversion properly, you need to add that final LF (unless the file is zero-length, i.e. has no lines in it at all). My favorite incantation for this (with a little added logic to handle Mac-style CR-separated files, and not molest files that're already in unix format) is a bit of perl:

perl -pe 'if ( s/\r\n?/\n/g ) { $f=1 }; if ( $f || ! $m ) { s/([^\n])\z/$1\n/ }; $m=1' PCfile.txt

注意,这将把文件的统一版本发送到标准输出。如果你想用一个统一的版本替换这个文件,添加perl的-i标志。