dos2unix - DOS/Mac - Unix文件格式转换器
dos2unix [选项] [文件 …] [-n 输入文件 输出文件 ...]
unix2dos [选项] [文件 …] [-n 输入文件 输出文件 ...]
Dos2unix软件包包括工具dos2unix
和 unix2dos
,用于将纯文本文件在DOS或Mac格式与Unix格式之间相互转换。
DOS/Windows的文本文件中,断行符是由两个字符共同表示的:回车符(CR)和换行符(LF)。Unix的文本文件中,换行符则由单个换行符(LF)表示。而Mac的文本文件则由单个回车符(CR,用于Mac OS X之前的系统)或单个换行符(LF,用于当下的新Mac OS)表示。
除了断行符,Dos2unix还可以转换文件编码。一些DOS编码页可以被转换为Unix Latin-1,Windows Unicode(UTF-16)文件也可以被转换为Unix Unicode(UTF-8)文件。
二进制文件则会被自动跳过,除非指定了强制转换选项。
特殊文件,如目录和队列,会被自动跳过。
符号链接和其所指向的目标默认不会被转换。可以用选项来指定替换符号链接,或者将输出写入到链接目标。Windows下不支持写入到符号链接的目标。
Dos2unix由SunOS/Solaris下的版本改写而成。这两个版本间有一个重大差异:本版本默认进行原位转换(旧文件模式),而原来SunOS/Solaris下的版本只支持配对转换(新文件模式),参见选项 -o
和 -n
。还有一个区别是SunOS/Solaris下的版本默认使用 iso 模式,而本版本默认使用 ascii 模式。
将后面所有的选项当作文件名。如果你希望转换一个文件名以破折号开头的文件,可以使用这个选项。例如,要转换一个名为“-foo”的文件,你可以用这个命令:
dos2unix -- -foo
或者在新文件模式下:
dos2unix -n -- -foo out.txt
在旧文件模式下,允许修改文件的所有者。
若使用此选项,将允许在转换文件时原始文件的属主或属组发生变更,类似于使用新文件模式进行转换。另请参见选项-o
和 -n
。仅当 dos2unix 支持保护文件的属主/属组时才能使用该选项。
默认转换模式。。参见 CONVERSION MODES 一节。
在DOS和ISO-8859-1字符集之间转换。参见 CONVERSION MODES 一节。
使用Windows 1252 编码页(西欧)。
使用DOS 437 编码页(美国)。这是ISO转换时的默认编码页。
使用DOS 850 编码页(西欧)。
使用DOS 860 编码页(葡萄牙)。
使用DOS 863 编码页(加拿大法语)。
使用DOS 865 编码页(北欧)。
将8位字符转换到7位空间。
保留字节序标记(BOM)。当输入文件含有BOM头时,也向输出文件写入BOM。这是转换到DOS断行符时的默认行为。参见选项 -r
。
改变转换模式。转换模式可以为:ascii、7bit、iso或mac,默认为ascii。
设置显示文本的编码。编码可以为:ansi、unicode、unicodebom、utf8、utf8bom,默认为 ansi。
这一选项只对支持Unicode文件名的Windows版dos2unix有效。它对文件名的读写无效,只影响它们的显示结果。
在Windows控制台中,有几种可以根据文本编码来显示文本的方法。它们各有利弊。
dos2unix默认使用ANSI编码文本。优点是它能提供向后兼容性,并能用于raster和TrueType字体。在一些地方,你可能需要使用 chcp
命令将活动DOS OEM编码页设置为Windows系统ANSI编码页,因为dos2unix使用Windows系统编码页。
ansi的缺点是含有非系统默认编码页中字符的国际化文件名将无法被正确显示。你会看到一些问号或其他错误的字符。如果你不需要处理外文文件名,这一方法是不错的选择。
Unicode编码(Windows中对UTF-16的称呼)的优点是文本可以被正确显示,也无需改变活动编码页。你可能需要设置终端字体为TrueType以便正确显示国际化字符。如果TrueType字体中不包含某个字符,你会看到一个小方块,有时方块中还会有一个问号。
当你使用ConEmu终端时,所以的文本将会被正确显示,因为ConEmu会自动选择合适的字体。
Unicode的缺点在于它与ASCII不兼容。当你将输出重定向到其他程序或文件时,它可能不那么容易控制
当使用 unicodebom
方法时,将会在Unicode文本前添加一个BOM(字节序标记)。在PowerShell中,需要根据BOM来进行正确的重定向或管道输出。
utf8的优点在于它与ASCII兼容。你需要设置终端的字体为TrueType字体。使用TrueType字体可以使得文本得以正确显示,就像使用 unicode
编码时那样。
缺点是当你使用默认的raster字体时,所有的非ASCII字符将无法被正确显示。不仅是unicode文件名,连翻译的消息也无法被读取。在配置为东亚地区的Windows中,当终端中显示这些消息时你可能会看到闪烁现象。
在ConEmu终端中,utf编码方式可以正常工作。
当使用 utf8bom
方法时,将会在Unicode文本前添加一个BOM(字节序标记)。在PowerShell中,需要根据BOM来进行正确的重定向或管道输出。
默认的编码方式可以通过设置 DOS2UNIX_DISPLAY_ENC 环境变量为 unicode
、unicodebom
、utf8
或 utf8bom
来改变。
如果文件末尾缺少换行符,则追加一个换行符。每次转换时均执行此操作。
从DOS转换至Unix格式的文件的末尾可能缺少换行符;部分文本编辑器也会主动忽略文本文件末尾的换行符。由于POSIX规范要求文本文件中的每一行必须以换行符结尾,部分Unix程序在处理此类缺少末尾换行符的文件时可能存在问题,例如:拼接两个文本文件时,第一个文件的最后一行会直接与第二个文件的第一行相连,从而产生非预期的结果。
强制转换二进制文件。
在Windows中,UTF-16默认被转换为UTF-8格式,无论区域设置为何。请使用这一选项将UTF-16文件转换为GB18030格式。此选项只在Windows下有效。参加 GB18030 一节。
显示帮助,然后退出。
显示文件信息。不进行转换。
将会显示下列信息(按顺序):DOS断行符的数量、Unix断行符的数量、Mac断行符的数量、是否有BOM、文本/二进制、文件名。
输出示例:
6 0 0 no_bom text dos.txt
0 6 0 no_bom text unix.txt
0 0 6 no_bom text mac.txt
6 6 6 no_bom text mixed.txt
50 0 0 UTF-16LE text utf16le.txt
0 50 0 no_bom text utf8unix.txt
50 0 0 UTF-8 text utf8dos.txt
2 418 219 no_bom binary dos2unix.exe
注意,二进制文件有时会被误判为文本文件。参见选项 -s
。
如果额外使用了 -e
或 --add-eol
选项,则最后一行的断行符类型也会被显示,或者在缺失的情况下显示 noeol
。
输出示例:
6 0 0 no_bom text dos dos.txt
0 6 0 no_bom text unix unix.txt
0 0 6 no_bom text mac mac.txt
1 0 0 no_bom text noeol noeol_dos.txt
可以为输出设置额外的标志(一个或多个)。
使用零字符("\0")而非换行符来分割文件信息行。用于在指定了 c 选项的情况下,正确解析含有空格或引号的文件名。请结合 xargs(1) 的选项 -0
或 --null
来使用。
显示DOS断行符的数量。
显示Unix断行符的数量。
显示Mac断行符的数量。
显示BOM状况。
显示文件为文本或二进制。
显示最后一行的断行符类型,如果不存在则显示 noeol
。
只显示将会被转换的文件。
若设置了 c
标志,dos2unix将只显示含有DOS断行符的文件,unix2dos将只显示含有Unix断行符的文件。
如果额外使用了 -e
或 --add-eol
选项,则最后一行缺失断行符的文件将被显示。
显示头部。
显示不含路径的文件名。
示例:
显示所有 *.txt 文件的信息:
dos2unix -i *.txt
只显示DOS断行符和Unix断行符的数量:
dos2unix -idu *.txt
只显示BOM状况:
dos2unix --info=b *.txt
列出含有DOS断行符的文件:
dos2unix -ic *.txt
列出含有Unix断行符的文件:
unix2dos -ic *.txt
列出含有DOS断行符或最后一行缺少断行符的文件:
dos2unix -e -ic *.txt
只转换含有DOS断行符的文件,保持其他文件不变:
dos2unix -ic0 *.txt | xargs -0 dos2unix
查找含有DOS断行符的文本文件:
find -name '*.txt' -print0 | xargs -0 dos2unix -ic
将输入文件的时间戳应用到输出文件。
显示程序许可证。
添加额外的新行。
dos2unix:只有DOS断行符会被转换为两个Unix断行符。在Mac模式下,只有Mac断行符会被转换为Unix断行符。
unix2dos:只有Unix断行符会被转换为两个DOS断行符。在Mac模式下,Unix断行符会被转换为两个Mac断行符。
将字节序标记(BOM)写入到输出文件。默认情况下将写入UTF-8 BOM。
当输入文件为UTF-16格式,并且使用了 -u
选项,将写入UTF-16 BOM。
当输出文件不是UTF-8、UTF-16或GB18030格式时,请不要使用此选项。参加 UNICODE 一节。
新文件模式。转换输入文件并写入到输出文件。文件名必须成对给出,并且 不能 使用通配符,否则你 将会丢失文件。
使用新文件(配对)模式转换时,命令执行者必须为文件的所有者。新文件的读/写权限将由源文件的权限减去命令执行者的 umask(1) 得到。
在旧文件模式下,不允许修改文件的所有者(默认选项)。
当原始文件的属主/属组无法保持不变时,停止格式转换。另请参见-o
和 -n
选项。仅当 dos2unix 支持保护文件的属主/属组时才能使用该选项。
即使文件末尾缺少换行符,也不要追加换行符。
将结果重定向至标准输出(类似Unix过滤器)。可以使用选项 -o
来切换回旧文件(原位修改)模式。
与选项 -e
一起使用时,可以确保拼接文件时上一个文件的最后一行不会错误地与下一个文件的第一行合并,且不会受到Unicode字节序记号的干扰。例如:
dos2unix -e -O file1.txt file2.txt > output.txt
旧文件模式。转换并将输出覆盖到源文件。程序默认使用此模式,允许使用通配符。
在旧文件(替换)模式下,被转换的文件的所有者、组和读/写权限保持不变。当文件被其他具有写权限的用户(如root)转换时,情况也是如此。如果无法保持这些值不变,转换将会终止。改变源文件的所有者可能造成其无法读取该文件,而改变组则可能带来安全隐患,使文件被不法分子读取。只有Unix才支持转换时保留所有者、组和读/写权限。
若要查看 dos2unix 是否支持保护文件的所有者,请输入dos2unix -V
。
dos2unix 在转换格式时会生成一个临时文件。如果在转换时出错,它会删除临时文件,从而保证原始文件不被更改;如果转换成功,将用临时文件替换原始文件。在这一过程中,如果 dos2unix 无法将临时文件的所有者设置为原始文件的所有者,那么新生成的文件也无法保留原始文件的属主/属组属性(即便您对原始文件有写入权限)。在这种情况下,可以使用--allow-chown
选项来继续进行转换:
dos2unix --allow-chown foo.txt
或者在新文件模式下:
dos2unix -n foo.txt foo.txt
使用--allow-chown
选项的好处在于:您可以使用通配符来操作文件,同时尽可能保持文件的所有者不变。
安静模式。不显示任何警告或信息。返回值为0,除非命令行选项有误。
移除字节序标记(BOM),不写入BOM到输出文件。这是转换到Unix断行符时的默认行为。参见选项 -b
。
跳过二进制文件(默认)。
跳过二进制文件是为了避免可能的错误。请注意,对二进制文件的探测并不能做到100%准确。程序通过扫描二进制文件所特有的标记来将其与文本文件区分开来,但有的二进制文件可能只包含普通的文本字符,这样的文件就会被误判为文本文件。
保留输入文件的UTF-16编码。输出文件也使用UTF-16编码和相同的尾序。这将阻止转换到UTF-8。相应也会写入UTF-16 BOM。可以用 -ascii
选项来禁止。
假定输入文件格式为UTF-16LE。
输入文件中有BOM时,将会覆盖此选项。
如果你做了错误的假设(输入文件不为UTF-16LE格式),并且转换成功,你将会得到一个错误的UTF-8格式的文件。你可以用 iconv(1) 来撤销转换,将其从UTF-8转换回UTF-16LE。这样做可以恢复源文件。
对UTF-16LE的假定将根据 l<转换模式> 来工作。若改变了默认的 l<ascii> 模式,则这一假定将会被关闭。
假定输入文件格式为UTF-16BE。
这一选项与 -ul
类似。
显示更多信息。将会显示有关BOM和转换统计的额外信息。
追踪符号链接并转换其目标。
将符号链接的目标替换为转换后的文件(原来的目标文件保持不变)。
保持符号链接和其目标文件不变(默认)。
显示版本信息,然后退出。
默认情况下断行符将从DOS格式转换为Unix格式,或相反。Mac格式的断行符将不会被转换。
Mac模式下,Mac断行符将被转换为Unix格式,或相反。DOS断行符将不会被转换。
若要以Mac模式运行,请使用命令行选项 -c mac
,或使用命令 mac2unix
或 unix2mac
。
这是默认转换模式。该模式用于转换ASCII和ASCII兼容编码的文件,例如UTF-8。启用ascii模式会禁用7bit和iso模式。
如果dos2unix带有UTF-16支持,则UTF-16编码的文件在POSIX系统上将被转换为当前语区对应的字符编码,在Windows上则会被转换为UTF-8。启用 ascii 模式将禁用维持UTF-16编码的选项(-u
)和假定输入为UTF-16的选项(-ul
和 -ub
)。如需查看dos2unix是否带有UTF-16支持,请运行 dos2unix -V
。更多信息另请参见 UNICODE 章节。
在此模式下,所以的8位非ASCII字符(取值范围128-255)将被转换到7位编码空间。
Unix下,将在DOS字符集(编码页)和ISO字符集 ISO-8859-1(Latin-1)之间进行转换。不具有 ISO-8859-1 中对等字符的DOS字符将会被转换为点号(“.”)。当 ISO-8859-1 字符集中没有DOS中的对等字符时也是如此。
当只指定了 -iso
选项时,dos2unix将尝试确定当前活动代码页。若无法确定,则使用默认代码页 CP437(普遍用于美国)。若要强制指定代码页,请使用选项 -437
(美国)、-850
(西欧)、-860
(葡萄牙)、-863
(法国、加拿大)或-865
(北欧)。 Windows CP1252代码页(西欧)也可以通过选项 -1252
获得支持。若要使用其他代码页,可以结合 iconv(1) 使用dos2unix。iconv可以在很多字符编码间进行转换。
不对Unicode编码文本使用ISO转换。因这一转换会导致UTF-8编码文件损坏。
一些示例:
从DOS默认编码页转换到Unix Latin-1:
dos2unix -iso -n in.txt out.txt
从DOS CP850转换到Unix Latin-1:
dos2unix -850 -n in.txt out.txt
从Windows CP1252转换到Unix Latin-1:
dos2unix -1252 -n in.txt out.txt
从WIndows CP1252转换到Unix UTF-8(Unicode):
iconv -f CP1252 -t UTF-8 in.txt | dos2unix > out.txt
从Unix Latin-1转换到DOS默认编码页:
unix2dos -iso -n in.txt out.txt
从Unix Latin-1转换到DOS CP850:
unix2dos -850 -n in.txt out.txt
从Unix Latin-1转换到Windows CP1252:
unix2dos -1252 -n in.txt out.txt
从Unix UTF-8(Unicode)转换到Windows CP1252:
unix2dos < in.txt | iconv -f UTF-8 -t CP1252 > out.txt
参见 http://czyborra.com/charsets/codepages.html et http://czyborra.com/charsets/iso8859.html。
有几种不同的Unicode编码。对于Unix和Linux中的Unicode文件,通常为UTF-8编码。Windows中的文本文件可以是UTF-8、UTF-16或UTF-16BE编码,但大多采用UTF-16格式。
Unicode文本文件可以含有DOS、Unix或Mac断行符,就像ASCII文本文件一样。
所有版本的dos2unix和unix2dos都可以转换UTF-8文件,因为UTF-8向后兼容ASCII。
含有Unicode UTF-16支持的dos2unix和unix2dos可以读取小尾序或大尾序的UTF-16编码文本。输入 dos2unix -V
来确定dos2unix在编译是是否启用了UTF-16支持。
在Unix/Linux中,UTF-16编码文件将被转换为区域字符编码所指定的编码。可以使用 locale(1) 命令来查看当前的区域字符编码。若无法转换,程序将报告转换错误并跳过此文件。
在Windows中,UTF-16文件被默认转换为UTF-8格式。Windows和Unix/Linux均支持UTF-8格式的文本文件。
UTF-16和UTF-8编码相互兼容,所以彼此转换时不会丢失文本。倘若转换中出错,比如UTF-16格式的输入文件含有错误,那么该文件将被跳过。
若使用了 -u
选项,输出文件将会使用和输入文件相同的UTF-16编码。-u
选项将阻止程序转换到UTF-8。
dos2unix和unix2dos没有用于转换UTF-8到UTF-16的选项。
ISO和7位编码模式的转换无法用于UTF-16文件。
在Windows中,文本文件一般含有字节序标记(BOM),因为很多Windows程序(包括记事本)默认添加BOM。参见 https://en.wikipedia.org/wiki/Byte_order_mark。
在Unix中,Unicode文件一般不含BOM。假定文本文件使用区域字符编码设置所指定的编码。
dos2unix只能检测含有BOM文件的UTF-16格式。若UTF-16文件不含BOM,dos2unix会将其视作二进制文件。
请使用选项 -ul
或 -ub
来转换不含BOM的UTF-16文件。
dos2unix默认不输出BOM。使用 -b
选项可以让dos2unix将BOM添加到输出文件,如果输入文件也含有BOM的话。
unix2dos默认输出BOM,如果输入文件也含有BOM的话。使用 -r
可以移除BOM。
若使用了 -m
选项,dos2unix和unix2dos将总是输出BOM。
dos2unix对于Windows命令提示符中读取和写入Unicode文件名有额外的支持。这意味着dos2unix可以打开那些包含非默认系统ANSI编码页字符的文件。若要查看Windows版dos2unix在编译时是否加入了Unicode文件名支持,请输入 dos2unix -V
。
在Windows终端中显示Unicode文件名有一些需要注意的问题。请参见 -D
和 --display-enc
选项。文件名在终端中可能无法被正确显示,但写入文件时文件名仍然是正确的。
转换Windows UTF-16到Unix UTF-8:
dos2unix -n in.txt out.txt
转换Windows UTF-16LE(不含BOM)到Unix UTF-8:
dos2unix -ul -n in.txt out.txt
转换Unix UTF-8到Windows UTF-8(并添加BOM):
unix2dos -m -n in.txt out.txt
转换Unix UTF-8到Windows UTF-16:
unix2dos < in.txt | iconv -f UTF-8 -t UTF-16 > out.txt
GB18030是中国国家标准。GB18030标准的一系列子集被强制应用于中国销售的软件产品。参见 https://en.wikipedia.org/wiki/GB_18030。
GB18030与Unicode完全兼容,并且可以被认为是Unicode格式的变体。和UTF-8一样,GB18030也兼容ASCII。GB18030也兼容Windows 936代码页(GBK)。
在Unix/Linux中,若区域编码被设置为GB18030,UTF-16文件将被转换为GB18030格式。注意只有当系统支持区域设置时这一才会进行这一转换。可以使用 locale -a
命令来获取受支持的区域。
在Windows中,你需要使用 -gb
选项来转换UTF-16文件到GB18030编码。
GB18030编码的文件和Unicode文件一样可以含有BOM。
从标准输入读取,并输出到标准输出:
dos2unix < a.txt
cat a.txt | dos2unix
转换并覆盖a.txt和b.txt:
dos2unix a.txt b.txt
dos2unix -o a.txt b.txt
转换并覆盖a.txt,使用ascii模式:
dos2unix a.txt
转换并覆盖a.txt,使用ascii模式;转换并覆盖b.txt,使用7位编码模式:
dos2unix a.txt -c 7bit b.txt
dos2unix -c ascii a.txt -c 7bit b.txt
dos2unix -ascii a.txt -7 b.txt
将a.txt从Mac格式转换到Unix格式:
dos2unix -c mac a.txt
mac2unix a.txt
将a.txt从Unix格式转换到Mac格式:
unix2dos -c mac a.txt
unix2mac a.txt
转换并覆盖a.txt,保留原始时间戳:
dos2unix -k a.txt
dos2unix -k -o a.txt
转换a.txt,并输出到e.txt:
dos2unix -n a.txt e.txt
转换a.txt,并输出到e.txt,同时使e.txt的时间戳和a.txt一致:
dos2unix -k -n a.txt e.txt
转换并覆盖a.txt;转换b.txt并输出到e.txt:
dos2unix a.txt -n b.txt e.txt
dos2unix -o a.txt -n b.txt e.txt
转换c.txt并输出到e.txt;转换并覆盖a.txt和b.txt;转换d.txt并输出到f.txt:
dos2unix -n c.txt e.txt -o a.txt b.txt -n d.txt f.txt
结合 find(1) 和 xargs(1) 使用 dos2unix 可以递归地转换目录树中的文本文件。例如,转换当前目录的目录树中所有的 .txt 文件:
dos2unix < a.txt
cat a.txt | dos2unix
若文件名中有空格或引号,则需要使用 find(1) 选项 -print0
及相应的 xargs(1) 选项 -0
;其他情况下则可以省略它们。也可以结合 -exec
选项来使用 find(1):
find . -name '*.txt' -exec dos2unix {} \;
在Windows命令提示符中,可以使用下列命令:
for /R %G in (*.txt) do dos2unix "%G"
PowerShell用户可以在Windows PowerShell中使用如下命令:
get-childitem -path . -filter '*.txt' -recurse | foreach-object {dos2unix $_.Fullname}
LANG环境变量指定了程序所使用的首选语言。它包括几个部分:第一部分是小写的语言编码,第二部分是(可选的)大写的国家/地区代码,前面用下划线连接;第三部分也是可选的,即字符编码,前面用点连接。一些POSIX规范的示例如下:
export LANG=zh 中文
export LANG=zh_CN 中文,中国
export LANG=zh_TW 中文,台湾
export LANG=es_ES 西班牙语,西班牙
export LANG=es_MX 西班牙语,墨西哥
export LANG=en_US.iso88591 英语,美国,Latin-1编码
export LANG=en_GB.UTF-8 英语,英国,UTF-8编码
完整的语言和国家/地区编码可以在gettext手册中找到:https://www.gnu.org/software/gettext/manual/html_node/Usual-Language-Codes.html
在Unix系统中,你可以使用 locale(1) 命令获取特定区域的信息。
可以使用LANGUAGE变量指定一系列语言的优先级,各项之间由冒号分割。dos2unix首先使用LANGUAGE变量,其次才是LANG。例如,首选中文、其次英文:LANGUAGE=<zh:en
。在使用语言优先级之前,必须先启用区域化功能,即将LANG(或LC_ALL)变量设置为除了“C”以外的其他值。参见gettext手册:https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html
如果你选择了一个不可用的语言,程序将会输出标准的英语信息。
DOS2UNIX_LOCALEDIR环境变量将覆盖编译时设置的LOCALEDIR变量。LOCALEDIR被用于查找语言文件。GNU程序的默认值为 /usr/local/share/locale
。可以使用 --version 查看当前的LOCALEDIR。
示例(POSIX shell):
export DOS2UNIX_LOCALEDIR=$HOME/share/locale
若成功,返回0。若出现系统错误,则返回最近一次系统错误号。若发生其他错误,返回1。
在安静模式下,返回值总是为0,除非命令行选项有误。
https://en.wikipedia.org/wiki/Text_file
https://en.wikipedia.org/wiki/Carriage_return
https://en.wikipedia.org/wiki/Newline
https://en.wikipedia.org/wiki/Unicode
Benjamin Lin - <blin@socs.uts.edu.au> Bernd Johannes Wuebben(mac2unix模式) - <wuebben@kde.org>,Christian Wurll(添加额外新行) - <wurll@ira.uka.de>,Erwin Waterlander - <waterlan@xs4all.nl>(维护者)
项目主页:https://waterlan.home.xs4all.nl/dos2unix.html
SourceForge主页:https://sourceforge.net/projects/dos2unix/
file(1) find(1) iconv(1) locale(1) xargs(1)