gpt4 book ai didi

linux - Sed 没有写入文件

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:35:11 26 4
gpt4 key购买 nike

我只想更改 CSV 上的分隔符。该文件来自外部服务器,因此分隔符是这样的:^A。

name^Atype^Avalue^A
john^Ab^A500
mary^Ac^A400
jack^Ad^A200

我想得到这个:

name,type,value
john,b,500
mary,c,400
jack,d,200

我需要将其更改为逗号 (,) 或制表符 (,),但我的 sed 命令尽管输出正确,但并未写入文件。

cat -v CSVFILE | sed -i "s/\^A/,/g"

当我使用上面的行时,它正确地输出了用逗号而不是 ^A 分隔的文件,但它没有写入文件。

我也这样试过:

sed -i "s/\^A/,/g" CSVFILE

也不行...我做错了什么?

最佳答案

  • 文字 ^A (两个字符,^A )是如何 cat -v 可视化控制字符0x1 (ASCII 码 1,命名为 SOH(标题开始))。 ^Acaret notation 的一个例子表示不可打印的 ASCII 字符:

    • ^A代表键盘组合 Control-A,当其前面有通用转义序列 Control-V 时,您可以创建实际 控制字符在您的终端;换句话说,
      Control-VControl-A 将插入实际的 0x1性格。

    • 顺便提一句,插入符号(^<letter>)的逻辑是:字母对应于所表示的控制字符的ASCII值;例如,A对应0x1 , 和 D对应0x4 ( ^D , EOT ).
      换句话说:您添加 0x40到控制字符的 ASCII 值,以获取其以脱字符号表示的字母表示的 ASCII 值。
      ^@代表NUL ( 0x0 个字符)和 ^?代表DEL ( 0x7f ) 与此符号一致,因为 @具有 ASCII 值 0x40 (即,它恰好在 ASCII 表中的 A ( 0x41 )之前)和 0x40 + 0x7f限制为 7 位(与最大 ASCII 值 0x7f 进行位与)产生 0x3f , 这是 ? 的 ASCII 值.

    • 检查给定文件的ASCII 值 外来控制字符,您可以将其通过管道传输到od -c,代表0x1作为(八进制)001 .

  • 这意味着,将文件传递给 sed直接,您不能使用插入符号,而必须在 s 中使用实际控制字符打电话。

    • 请注意,当您使用Control-VControl-A 创建一个实际 0x1字符,它也将出现在插入符号中 - 作为 ^A - 但在那种情况下,它只是终端对真正控制字符的可视化;虽然它可能看起来像两个可打印字符 ^A ,它不是。纯粹从视觉上看不出区别 - 这就是为什么使用转义序列或 ANSI C 引号字符串来表示控制字符是更好的选择 - 见下文。
  • 假设您的 shell 是 bash , ksh , 或 zsh ,使用 Control-VControl-A 的更好替代方法是使用 ANSI C-quoted string生成 0x1字符:$'\1'

    • 然而,作为Lars Fischer在对该问题的评论中指出,GNU sed还识别转义序列 \x01 对于 0x1 .

因此,您的命令应该是:

sed -i 's/\x01/,/g' CSVFILE    # \x01 only recognized by GNU sed

或者,使用 ANSI C 引号字符串:

sed -i $'s/\1/,/g' CSVFILE  

注意:虽然这种形式原则上可以用于BSD/OSX sed -i语法略有不同:您必须使用 sed -i '' $'s/\1/,/g' CSVFILE


使用sed的唯一理由您的任务是利用就地更新 ( -i );否则,tr是更好的选择 - 请参阅 Ed Morton's answer .

关于linux - Sed 没有写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35660194/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com