0

我正在尝试unix2dos在一组 C++ 源代码文件上使用。基本上,unix2dos将 LF 转换为 CRLF。

我可以简单地执行以下操作,它会做我想要的:

#!/bin/sh
find . -type f \( -name "*.h" -o -name "*.cpp" \) -exec unix2dos {}\;

但如果文件已经有 CRLF 行尾,我不希望文件被修改。这就是为什么我必须修改脚本。

#!/bin/sh
for i in `find . -type f \( -name "*.h" -o -name "*.cpp" \)` 
do
  LINE=`file $i | grep CRLF`
  if [ $? -eq 1 ]
  then
    unix2dos $i
  fi
done

由于没有正确处理空格,因此该for循环似乎有点难以使用。当文件名包含空格时,shell 会尝试在拆分的字符串上错误地应用 unix2dos。

我该如何解决这个问题?

4

5 回答 5

3

您可以使用以下 perl,它应该保持 CRLF 文件不变:

#!/bin/sh
find . -type f \( -name "*.h" -o -name "*.cpp" \) -exec perl -pi -e 's/([^\r])\n/$1\r\n/' "{}"\;

它将在任何前面没有 CR 的 LF 之前插入一个 CR。

于 2013-12-12T17:06:00.930 回答
1
  • 您不应该在 for 循环中处理 find 命令的输出。

  • 您需要在 shell 中正确引用变量。

试试这个代码:

#!/bin/sh
find . -type f \( -name "*.h" -o -name "*.cpp" \) | while read i
do
  LINE=`file "$i" | grep -c CRLF`
  if [ $LINE -eq 0 ]
  then
    unix2dos "$i"
  fi
done

更新:如果您决定使用 BASH,那么您可以更有效地执行此循环。考虑以下代码:

#!/bin/bash
while read file
do
  grep -q $'\r'"$" "$file" && unix2dos "$file"
done < <(find . -type f \( -name "*.h" -o -name "*.cpp" \))

< <(...)语法称为进程替换,它在当前 shell 本身中进行上述 while 循环,从而允许您在当前 shell 进程中设置 shell 变量并保存子 shell 创建的分叉。

于 2013-12-12T16:45:37.203 回答
1

您可以使用 a 检查grep文件是否包含 a\runix2dos有条件地运行,如下所示:

find . -type f \( -name "*.h" -o -name "*.cpp" \) -exec sh -c 'grep -q ^M "{}" && dos2unix "{}"' \;

...您^M通过按 Control-V 和 Enter 输入的位置。(^M\r字符)

于 2013-12-12T19:03:11.370 回答
1

只需使用以下命令更改您的unix2dos命令(由 putnamhill upper 提供):

`perl -wpi -e 's/([^\r])\n/$1\r\n/g' $1`;

然后执行您之前的find命令:

#!/bin/sh
find . -type f \( -name "*.h" -o -name "*.cpp" \) -exec unix2dos {}\;

你都准备好了。

于 2013-12-13T09:25:33.333 回答
0

Unix2dos 会将 LF 更改为 CRLF,但不会将 CRLF 更改为 CRCRLF。任何现有的 DOS 换行符将保持不变。所以做你想做的最简单的方法是:

unix2dos *.h *.cpp

最好的问候,欧文

于 2013-12-16T08:24:01.693 回答