将Mac的换行格式转换为Windows

151

我需要一个转换工具/脚本,可以将在Mac上生成的.sql转储文件转换为Windows上可读取的文件格式。这是我在这里遇到的问题的继续。问题似乎出现在文本文件中的换行符格式上,但我找不到可以进行转换的工具...


4
这是我在未能找到符合工业标准的满意解决方案后,制作的通用工具。链接为 https://github.com/mdolidon/endlines。 - Mathias Dolidon
12个回答

148

Windows使用回车符 + 换行符表示换行:

\r\n

Unix 只使用 LF(Line feed) 作为换行符:

\n

总之,只需将每个 \n 替换为 \r\n


在Mac OSX上,默认情况下都没有 unix2dosdos2unix 工具。
不过,你可以简单地使用 Perlsed 来完成此任务:

sed -e 's/$/\r/' inputfile > outputfile                # UNIX to DOS  (adding CRs)
sed -e 's/\r$//' inputfile > outputfile                # DOS  to UNIX (removing CRs)
perl -pe 's/\r\n|\n|\r/\r\n/g' inputfile > outputfile  # Convert to DOS
perl -pe 's/\r\n|\n|\r/\n/g'   inputfile > outputfile  # Convert to UNIX
perl -pe 's/\r\n|\n|\r/\r/g'   inputfile > outputfile  # Convert to old Mac

代码片段来自:
http://en.wikipedia.org/wiki/Newline#Conversion_utilities


37
在OS X Lion上,用于将UNIX格式转换为DOS格式的sed命令对我无效 - 它只是在每行末尾插入文本“r”。 不过,perl命令可以正常工作。 - Ergwun
7
OSX使用旧版本的sed。我在OSX上使用Homebrew,并安装了gnu-sed。你需要使用"gsed"命令代替"sed"。这样可以正常工作。 - John
3
请使用Homebrew获取dos2unix和unix2dos软件包。 - Pratyush
11
OS X Yosemite在使用sed命令时仍然存在相同的问题,但您可以避免安装Homebrew、gnu-sed或unix2dos来解决它:使用sed -e 's/$/^M/' inputfile > outputfile命令即可。其中,^M是通过在命令行上按Ctrl+V Ctrl+M组合键产生的控制字符。请注意不改变原文意思,并使翻译更加通俗易懂。 - LarsH
3
另一种适用于Mac OS(在10.13.6 High Sierra上测试过)的解决方法:在包含sed命令的单引号前面加上$符号:sed $'s/\r$//'。说明:bash会解码$'...'字符串中的反斜杠转义字符。有关详细信息,请参见https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html。 - jcsahnwaldt Reinstate Monica
显示剩余2条评论

136

如果您使用perl,这是Anne答案的改进版本--您可以对文件进行“原地”编辑而不是生成新文件:

perl -pi -e 's/\r\n|\n|\r/\r\n/g' file-to-convert  # Convert to DOS
perl -pi -e 's/\r\n|\n|\r/\n/g'   file-to-convert  # Convert to UNIX

5
这些脚本的非常棒之处在于,它们使用正则表达式精确地展示了从任何格式开始,需要做哪些行尾转换才能将其转换为任一格式。 - pbr
在Windows系统的某些Cygwin/git bash安装中要小心。 这可能会导致Can't do inplace edit on file: Permission denied.删除文件。请考虑使用其他工具。 - Dennis
非常感谢您展示“转换为Unix”的方法。我一直在寻找这种方式,您的双重答案帮助了我,并得到了我的赞同。 - null

131

您可以使用Homebrew安装unix2dos。

brew install unix2dos

然后你可以这样做:

unix2dos file-to-convert

你也可以将 DOS 文件转换为 Unix 格式:

dos2unix file-to-convert

10
如果有人现在遇到这个问题,Homebrew的公式现在被称为“dos2unix”。你需要执行“brew install dos2unix”命令。 - Geoff
15
实际上,brew install unix2dosbrew install dos2unix 两者都可以正常工作。它们安装的是相同的软件包。使用你喜欢的任何名称即可 :) - Steven Hirlston
2
或者使用Macportsport install dos2unix - Fang

17

你可能想要使用unix2dos工具:

$ man unix2dos

NAME
       dos2unix - DOS/MAC to UNIX and vice versa text file format converter

SYNOPSIS
           dos2unix [options] [-c CONVMODE] [-o FILE ...] [-n INFILE OUTFILE ...]
           unix2dos [options] [-c CONVMODE] [-o FILE ...] [-n INFILE OUTFILE ...]

DESCRIPTION
       The Dos2unix package includes utilities "dos2unix" and "unix2dos" to convert plain text files in DOS or MAC format to UNIX format and vice versa.  Binary files and non-
       regular files, such as soft links, are automatically skipped, unless conversion is forced.

       Dos2unix has a few conversion modes similar to dos2unix under SunOS/Solaris.

       In DOS/Windows text files line endings exist out of a combination of two characters: a Carriage Return (CR) followed by a Line Feed (LF).  In Unix text files line
       endings exists out of a single Newline character which is equal to a DOS Line Feed (LF) character.  In Mac text files, prior to Mac OS X, line endings exist out of a
       single Carriage Return character. Mac OS X is Unix based and has the same line endings as Unix.

你可以在你的DOS/Windows机器上使用cygwin或者在你的Mac上使用MacPorts运行unix2dos


unix2dos/dos2unix在我的Mac上不存在,我也没有找到任何安装它们的地方 - 你知道吗? - Yarin
@mgadda:+1 - 是的,我一段时间前从MacPorts转到了Homebrew,现在再也没有回头看过。 - Paul R

17

只需执行tr删除操作:

tr -d "\r" <infile.txt >outfile.txt

2
尝试了Perl和sed,但都没有成功(我本来可以弄明白的,但不值得尝试)。这个方法非常好用。 - RandomInsano
这是我找到的第一个解决方案,用Python读取BBEdit的行号与行数不匹配(也不匹配wc -l)。 - Daryl Spitzer
1
这将删除所有的换行符,但我实际上仍然需要有换行符,只是使用 \n。 - UserYmY
"http://hints.macworld.com/article.php?story=20031018164326986" 这篇文章详细介绍了如何使用 tr 命令进行各种转换。使用 hexdump 或类似工具来查找文件中现在使用的确切行尾约定。 - Mike Robinson

9
  1. 使用Homebrew安装dos2unix
  2. 运行find ./ -type f -exec dos2unix {} \;来递归地转换当前文件夹内的所有行尾结束符

5

vim也可以将UNIX格式的文件转换为DOS格式。例如:

vim hello.txt <<EOF
:set fileformat=dos
:wq
EOF

相反地,如果你需要从DOS转移到UNIX:

vim hello.txt <<EOF
:set fileformat=unix
:wq
EOF

运行得很好,只需要将 DOS 改为 Unix 适用于 Mac。 - Harish Jangra
要执行相反的操作,只需使用 :set fileformat=unix。我更新了我的答案以反映这一点。 - Stephen Quan

2

这里有一个非常简单的方法,对我很有帮助,感谢Davy Schmeits的博客:

cat foo | col -b > foo2

其中foo是文件名,该文件在每行末尾带有Control+M字符,foo2是你要创建的新文件名。


2
以下是一份完整的脚本,基于以上答案进行了合理性检查,并适用于Mac OS X系统,应该也适用于其他Linux / Unix系统(尽管未经过测试)。
#!/bin/bash

# https://dev59.com/amw15IYBdhLWcg3w0fKh

# =============================================================================
# =
# = FIXTEXT.SH by ECJB
# =
# = USAGE:  SCRIPT [ MODE ] FILENAME
# =
# = MODE is one of unix2dos, dos2unix, tounix, todos, tomac
# = FILENAME is modified in-place
# = If SCRIPT is one of the modes (with or without .sh extension), then MODE
# =   can be omitted - it is inferred from the script name.
# = The script does use the file command to test if it is a text file or not,
# =   but this is not a guarantee.
# =
# =============================================================================

clear
script="$0"
modes="unix2dos dos2unix todos tounix tomac"

usage() {
    echo "USAGE:  $script [ mode ] filename"
    echo
    echo "MODE is one of:"
    echo $modes
    echo "NOTE:  The tomac mode is intended for old Mac OS versions and should not be"
    echo "used without good reason."
    echo
    echo "The file is modified in-place so there is no output filename."
    echo "USE AT YOUR OWN RISK."
    echo
    echo "The script does try to check if it's a binary or text file for sanity, but"
    echo "this is not guaranteed."
    echo
    echo "Symbolic links to this script may use the above names and be recognized as"
    echo "mode operators."
    echo
    echo "Press RETURN to exit."
    read answer
    exit
}

# -- Look for the mode as the scriptname
mode="`basename "$0" .sh`"
fname="$1"

# -- If 2 arguments use as mode and filename
if [ ! -z "$2" ] ; then mode="$1"; fname="$2"; fi

# -- Check there are 1 or 2 arguments or print usage.
if [ ! -z "$3" -o -z "$1" ] ; then usage; fi

# -- Check if the mode found is valid.
validmode=no
for checkmode in $modes; do if [ $mode = $checkmode ] ; then validmode=yes; fi; done
# -- If not a valid mode, abort.
if [ $validmode = no ] ; then echo Invalid mode $mode...aborting.; echo; usage; fi

# -- If the file doesn't exist, abort.
if [ ! -e "$fname" ] ; then echo Input file $fname does not exist...aborting.; echo; usage; fi

# -- If the OS thinks it's a binary file, abort, displaying file information.
if [ -z "`file "$fname" | grep text`" ] ; then echo Input file $fname may be a binary file...aborting.; echo; file "$fname"; echo; usage; fi

# -- Do the in-place conversion.
case "$mode" in
#   unix2dos ) # sed does not behave on Mac - replace w/ "todos" and "tounix"
#       # Plus, these variants are more universal and assume less.
#       sed -e 's/$/\r/' -i '' "$fname"             # UNIX to DOS  (adding CRs)
#       ;;
#   dos2unix )
#       sed -e 's/\r$//' -i '' "$fname"             # DOS  to UNIX (removing CRs)
#           ;;
    "unix2dos" | "todos" )
        perl -pi -e 's/\r\n|\n|\r/\r\n/g' "$fname"  # Convert to DOS
        ;;
    "dos2unix" | "tounix" )
        perl -pi -e 's/\r\n|\n|\r/\n/g'   "$fname"  # Convert to UNIX
        ;;
    "tomac" )
        perl -pi -e 's/\r\n|\n|\r/\r/g'   "$fname"  # Convert to old Mac
        ;;
    * ) # -- Not strictly needed since mode is checked first.
        echo Invalid mode $mode...aborting.; echo; usage
        ;;
esac

# -- Display result.
if [ "$?" = "0" ] ; then echo "File $fname updated with mode $mode."; else echo "Conversion failed return code $?."; echo; usage; fi

0

在Anne和JosephH的答案基础上进行扩展,使用Perl编写短小的Perl脚本,因为我懒得每次都输一遍Perl单行脚本。
创建一个文件,例如命名为"unix2dos.pl"并将其放置在您的路径目录中。编辑该文件以包含以下2行:

#!/usr/bin/perl -wpi
s/\n|\r\n/\r\n/g;

假设“which perl”在您的系统上返回“/usr/bin/perl”。将文件设置为可执行(chmod u+x unix2dos.pl)。
例子: $ echo "hello" > xxx $ od -c xxx (检查文件以nl结尾) 0000000 h e l l o \n $ unix2dos.pl xxx $ od -c xxx (检查现在以cr lf结尾) 0000000 h e l l o \r \n

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接