我正在尝试在一组C ++源代码文件上使用unix2dos
。基本上,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。
如何解决问题?
答案 0 :(得分: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。
答案 1 :(得分: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" \))
< <(...)
语法称为process substitution,它在当前shell本身的while循环中生成,因此允许您在当前shell进程中设置shel变量并保存子shell创建的分支。
答案 2 :(得分:1)
如果文件包含grep
并且有条件地运行\r
,您可以使用unix2dos
查看,如下所示:
find . -type f \( -name "*.h" -o -name "*.cpp" \) -exec sh -c 'grep -q ^M "{}" && dos2unix "{}"' \;
...按Control-V和Enter键输入^M
。 (^M
是\r
个字符)
答案 3 :(得分:1)
只需使用以下内容(由putnamhill upper提供)更改unix2dos
命令:
`perl -wpi -e 's/([^\r])\n/$1\r\n/g' $1`;
然后执行上一个find
命令:
#!/bin/sh
find . -type f \( -name "*.h" -o -name "*.cpp" \) -exec unix2dos {}\;
你们已经定下来了。
答案 4 :(得分:0)
Unix2dos会将LF更改为CRLF,但不会将CRLF更改为CRCRLF。任何现有的DOS换行符都将保持不变。所以做你想做的最简单的方法是:
unix2dos * .h * .cpp
最好的问候, 欧文