仅从变量而不是文件中删除换行符 (^M) 的方法

仅从变量而不是文件中删除换行符 (^M) 的方法

我正在将文件加载到变量中,问题是该文件是在 Windows 中格式化的,我相信,所以我得到的是一个^M而不是换行符。

当值在变量中时,如何修改它?我知道我可以在 VI 中修改源代码(顺便说一句,我使用 OS X),但我无法修改原始文件,只能读取它,所以我必须^M从变量中删除 。

据我了解,\n与 不同^M,因此tr命令不起作用。

编辑

看来问题没说清楚;这就是澄清。

我确实逐行解析文件;每行有 2 个值,用制表符分隔,每行末尾有一个 ^M,它看起来像这样:

value1    value2^M
value3    value4^M
value5    value6^M
value7    value8^M

我的工作流程非常简单明了:txt 文件包含您在上面看到的内容,循环单独的字段并为每一行获取值;当我打印第二个值时,它有 ^M,我想删除它

while IFS=$'\t' read -r -a line
do
    Type1="${line[0]}"
    Type2="${line[1]}"
done < $TXTFILE

这意味着当我打印 Type1 时,它没问题,但 Type2 变量包含 ^M。我确实使用过tr,但不起作用,我确实使用过sed删除变量的最后一个字符,但它不起作用。希望这能澄清我的问题。谢谢

答案1

^M是一个回车符 (CR),可以指定为\rfortr或 inside $'…'\n指定换行符 (LF),即^J. Unix 行结尾是 LF,Windows 行分隔符是两个字符序列 CR-LF,因此在 Linux 或 macOS 等 Unix 系统下查看的 Windows 文本文件看起来就像^M在每行末尾(除了最后一行)缺少最后换行符的行。

tr您可以使用 with从文件中删除回车符

tr -d '\r' <somefile.txt >somefile.txt.new && mv somefile.txt.new somefile.txt

或者更简单地使用dos2unix.

为了避免修改文件,您可以在读取文件时检查每一行,并在行尾去掉 CR。例如,如果您要用来read解析制表符分隔的值,则在最后一个字段的末尾去掉 CR。参数扩展${VAR%$'\r'}产生减去尾随 CR 的值,如果不以 CR 结尾则VAR产生 的值。VAR

while IFS=$'\t' read -r -a line
do
    line[$((${#line[@]}-1))]="${line[$((${#line[@]}-1))]%$'\r'}"
    Type1="${line[0]}"
    Type2="${line[1]}"
done < "$TXTFILE"

答案2

这是修复脚本的最简单方法,只需添加“回车符”作为读取命令的内部字段分隔符:

而 IFS=$'\t\r' 读取 -r -a 行
  类型1=“${行[0]}”
  类型2=“${行[1]}”
完成 < $TXTFILE

答案3

使用(对于短字符串):

${var//$'\015'}

例子:

$ var=$'This is a test of a CR (\r) character'
$ echo "${var//$'\r'}"
This is a test of a CR () character

对于较长的字符串,您可能需要 sed 或 awk。

答案4

转换“DOS”文件内容的更普遍有用的方法,这些文件除了 CR+LF 行结尾之外没有其他内容标记(与 Linux 的仅 LF 相比)。

对于 Ubuntu,第一次且仅一次,执行以下操作

sudo apt install dos2unix

使用如下所示,这里od用于验证输出

$ dos2unix < $TXTFILE | od -t x1z -w17
0000000 76 61 6c 75 65 31 20 20 20 20 76 61 6c 75 65 32 0a >值1 值2。<
0000021 76 61 6c 75 65 33 20 20 20 20 76 61 6c 75 65 34 0a >值3 值4.<
0000042 76 61 6c 75 65 35 20 20 20 20 76 61 6c 75 65 36 0a >值5 值6.<
0000063 76 61 6c 75 65 37 20 20 20 20 76 61 6c 75 65 38 0a >值7 值8。<
0000104

$ 猫 $TXTFILE | od -t x1z -w18
0000000 76 61 6c 75 65 31 20 20 20 20 76 61 6c 75 65 32 0d 0a >值1 值2..<
0000022 76 61 6c 75 65 33 20 20 20 20 76 61 6c 75 65 34 0d 0a >值3 值4..<
0000044 76 61 6c 75 65 35 20 20 20 20 76 61 6c 75 65 36 0d 0a >值5 值6..<
0000066 76 61 6c 75 65 37 20 20 20 20 76 61 6c 75 65 38 0d 0a >值7 值8..<
0000110

这不仅会翻译行结尾,还会翻译其他特殊字符,具体取决于参数dos2unix或其对应项unix2dos(同时安装)。

相关内容