88

我是一名 Java 开发人员,我正在使用 Ubuntu 进行开发。该项目是在带有 Eclipse 的 Windows 中创建的,它使用Windows-1252编码。

为了转换为 UTF-8,我使用了recode程序:

find Web -iname \*.java | xargs recode CP1252...UTF-8

此命令给出此错误:

recode: Web/src/br/cits/projeto/geral/presentation/GravacaoMessageHelper.java failed: Ambiguous output in step `CR-LF..data

我已经对其进行了搜索并在Bash 和 Windows 中找到了解决方案,重新编码:步骤 `data..CR-LF' 中的模棱两可的输出,它说:

将行尾从 CR/LF 转换为单个 LF:用 Vim 编辑文件,给出命令:set ff=unix并保存文件。现在重新编码应该可以正常运行。

很好,但是我有很多文件要从中删除 CR/LF 字符,而且我无法打开每个文件来执行此操作。Vi 没有为 Bash 操作提供任何命令行选项。

可以使用 sed 来执行此操作吗?如何?

4

8 回答 8

128

应该有一个程序dos2unix可以为您修复行尾。如果它还没有在你的 Linux 机器上,它应该可以通过包管理器获得。

于 2010-10-08T13:40:22.060 回答
96

sed无法匹配\n,因为在将行放入模式空间之前删除了尾随换行符,但它可以匹配\r,因此您可以通过删除 \r将\r\n(DOS) 转换为(Unix):\n

sed -i 's/\r//g' file

警告:这将更改原始文件

但是,您不能由此从 Unix EOL 更改为 DOS 或旧 Mac ( \r)。更多阅读在这里:

如何使用 sed 替换换行符 (\n)?

于 2013-10-09T21:51:32.407 回答
15

实际上,Vim 确实允许您查找所需的内容。输入 Vim,然后键入以下命令:

:args **/*.java
:argdo set ff=unix | update | next

这些命令中的第一个以**/*.java递归方式将参数列表设置为每个匹配的文件,即所有 Java 文件。这些命令中的第二个依次对参数列表中的每个文件执行以下操作:

  • 将行尾设置为 Unix 风格(你已经知道了)
  • 如果文件已被更改,则将文件写出
  • 继续下一个文件
于 2014-08-19T13:59:11.350 回答
11

我对jichao的回答有点例外。你实际上可以很容易地完成他刚才所说的一切。无需寻找\n,只需在行尾寻找回车即可。

sed -i 's/\r$//' "${FILE_NAME}"

要从 Unix 改回 DOS,只需查找行中的最后一个字符并为其添加换页符。(我将添加-rgrep 正则表达式以使这更容易。)

sed -ri 's/(.)$/\1\r/' "${FILE_NAME}"

从理论上讲,可以通过在最后一个示例中添加代码来将文件更改为 Mac 样式,该示例还将下一行输入附加到第一行,直到所有行都已处理完毕。不过,我不会在这里举这个例子。

警告: -i更改实际文件。如果要进行备份,请在 . 后面添加一串字符-i。这会将现有文件移动到具有相同名称的文件中,并将您的字符添加到末尾。

更新: Unix 到 DOS 的转换可以被简化并且通过不费心寻找最后一个字符来提高效率。这也允许我们不需要使用 -r 来工作:

sed -i 's/$/\r/' "${FILE_NAME}"
于 2017-05-26T20:51:01.730 回答
9

tr 命令也可以这样做:

tr -d '\15\32' < winfile.txt > unixfile.txt

并且应该可供您使用。

您需要在脚本中运行 tr,因为它不能使用文件名。例如,创建一个文件 myscript.sh:

#!/bin/bash

for f in `find -iname \*.java`; do
    echo "$f"
    tr -d '\15\32' < "$f" > "$f.tr"
    mv "$f.tr" "$f"
    recode CP1252...UTF-8 "$f"
done

运行myscript.sh将处理当前目录及其子目录中的所有 java 文件。

于 2010-10-08T13:44:01.277 回答
5

为了克服

Ambiguous output in step `CR-LF..data'

简单的解决方案可能是添加-f标志来强制转换。

于 2012-05-16T13:29:59.173 回答
0

尝试在这里找到的 Bryan Maupin 的 Python 脚本(我对其进行了一些修改以使其更通用):

#!/usr/bin/env python

import sys

input_file_name = sys.argv[1]
output_file_name = sys.argv[2]

input_file = open(input_file_name)
output_file = open(output_file_name, 'w')

line_number = 0

for input_line in input_file:
    line_number += 1
    try:  # first try to decode it using cp1252 (Windows, Western Europe)
        output_line = input_line.decode('cp1252').encode('utf8')
    except UnicodeDecodeError, error:  # if there's an error
        sys.stderr.write('ERROR (line %s):\t%s\n' % (line_number, error))  # write to stderr
        try:  # then if that fails, try to decode using latin1 (ISO 8859-1)
            output_line = input_line.decode('latin1').encode('utf8')
        except UnicodeDecodeError, error:  # if there's an error
            sys.stderr.write('ERROR (line %s):\t%s\n' % (line_number, error))  # write to stderr
            sys.exit(1)  # and just keep going
    output_file.write(output_line)

input_file.close()
output_file.close()

您可以使用该脚本

$ ./cp1252_utf8.py file_cp1252.sql file_utf8.sql
于 2010-12-08T15:49:01.467 回答
-1

返回 Windows,告诉 Eclipse 将编码更改为 UTF-8,然后返回 Unix 并d2u在文件上运行。

于 2010-10-08T14:10:57.267 回答