如何检查文本文件的行尾,以确定它是unix格式还是dos格式?

如何检查文本文件的行尾,以确定它是unix格式还是dos格式?,unix,dos,ksh,end-of-line,Unix,Dos,Ksh,End Of Line,我需要将文本文件转换为dos格式(如果文件是unix格式(0x0a仅在每一行末尾),则每一行的结尾都是0x0a) 我知道如何转换它(sed的/$/^M/”),但不知道如何检测文件的行尾字符 我正在使用ksh 任何帮助都将不胜感激 [更新]: 这是我的ksh脚本,用于执行检查 [qiangxu@host:/my/folder]# cat eol_check.ksh #!/usr/bin/ksh if ! head -1 $1 |grep ^M$ >/dev/null 2>&1

我需要将文本文件转换为dos格式(如果文件是unix格式(
0x0a
仅在每一行末尾),则每一行的结尾都是
0x0a

我知道如何转换它(
sed的/$/^M/”
),但不知道如何检测文件的行尾字符

我正在使用ksh

任何帮助都将不胜感激

[更新]: 这是我的ksh脚本,用于执行检查

[qiangxu@host:/my/folder]# cat eol_check.ksh
#!/usr/bin/ksh

if ! head -1 $1 |grep ^M$ >/dev/null 2>&1; then
  echo UNIX
else
  echo DOS
fi
在上述脚本中,
^M
应使用
Ctrl-V
Ctrl-M
插入
vi


想知道是否有更好的方法。

只需使用
文件
命令即可。 如果文件末尾包含带有
CR LF
的行,则通过注释打印出来: 'ASCII文本,带CRLF行终止符'

e、 g


我无法在AIX上测试,但请尝试:

if [[ "$(head -1 filename)" == *$'\r' ]]; then echo DOS; fi

您只需从所有行中删除任何现有的回车符,然后将回车符添加到所有行的末尾。那么传入文件的格式就无关紧要了。输出格式将始终为DOS格式

sed 's/\r$//;s/$/\r/'
最新(7.1)版本的dos2unix(和unix2dos)命令与Cygwin和一些最新的Linux发行版一起安装,它有一个方便的--info选项,可以打印出每个文件中不同类型换行符的计数。这是dos2unix 7.1(2014-10-06)

从手册页:

--info[=FLAGS] FILE ...
       Display file information. No conversion is done.

The following information is printed, in this order: 
number of DOS line breaks, number of Unix line breaks, number of Mac line breaks, byte order mark, text or binary, file name.

       Example output:
            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

Optionally extra flags can be set to change the output. One or more flags can be added.
       d   Print number of DOS line breaks.
       u   Print number of Unix line breaks.
       m   Print number of Mac line breaks.
       b   Print the byte order mark.
       t   Print if file is text or binary.
       c   Print only the files that would be converted.

With the "c" flag dos2unix will print only the files that contain DOS line breaks, unix2dos will print only file names that have Unix line breaks.
因此:

相反地:

if [[ -n $(unix2dos --info=c "${filename}") ]] ; then echo UNIX; fi

我可能在这一点上迟到了,但我也遇到了同样的问题,我不想在我的脚本中添加特殊的
^m
字符(我担心一些编辑器可能无法正确显示特殊字符,或者一些后来的程序员可能会将其替换为2个普通字符:^和m…)

我找到的解决方案通过让shell转换其十六进制值,将特殊字符提供给grep:

if head -1 ${filename} | grep $'[\x0D]' >/dev/null
then
  echo "Win"
else
  echo "Unix"
fi
不幸的是,我无法使
$'[\x0D]'
构造在ksh中工作。 在ksh中,我发现: 如果head-1${filename}|od-x | grep'0d0a$'>/dev/null 然后 呼应“胜利” 其他的 回声“Unix” fi

od-x
以十六进制代码显示文本。
'0d0a$'
是CR-LF(DOS赢线终止符)的十六进制代码。Unix行终止符是
'0a00$”

然而,我的AIX机器中的ksh只告诉我
test.txt:ascii text
,而不管
test.txt
中使用的是哪种行尾。它没有告诉我是否包含CRLF。它对我不起作用,总是说文件是UNIX格式的,而文件实际上是DOS格式的。这是一种解决方法。但是
\r
不起作用。它需要替换为
^M
vi
的插入模式下的
Ctrl-V
Ctrl-M
)。不过,我不想一路这么做。有没有办法检查txt文件的行尾字符?@QiangXu-我不是sed的普通用户,我更喜欢Windows,所以我不确定。但我相信您需要regex look-behind特性,我认为sed不支持该特性。
if [[ -n $(dos2unix --info=c "${filename}") ]] ; then echo DOS; fi
if [[ -n $(unix2dos --info=c "${filename}") ]] ; then echo UNIX; fi
if head -1 ${filename} | grep $'[\x0D]' >/dev/null
then
  echo "Win"
else
  echo "Unix"
fi