【问题标题】:sed copy substring from fixed position and copy it in front of linesed 从固定位置复制子字符串并将其复制到行前
【发布时间】:2013-05-13 20:56:31
【问题描述】:

我正在处理许多 csv 文件,但我找不到使用 sed 选择固定位置 (chars 9-16) 的子字符串并将其复制到开头的方法行。

这就是我所拥有的:

ABC09638006924340017;SOME_TEXT;SOME_OTHER_TEXT

这是我需要的:

00692434;ABC09638006924340017;SOME_TEXT;SOME_OTHER_TEXT

sed 中的以下代码给出了我需要的子字符串 (00692434) 但会覆盖整行:

sed 's/^.{8}(.{8}).*/\1/')

我已经在使用 sed 来“清理”线串并插入一些变量,这些变量在 bash 脚本中调用,最后在 postgres 中导入数据。这就是为什么我更愿意留在 sed 中的原因,但是任何提示都将不胜感激,因为我不是真正的专家。

【问题讨论】:

    标签: bash csv sed substring


    【解决方案1】:

    您需要转义大括号 (\{\}) 以及括号 (\(\)),并在替换中附加原始字符串 (&):

    text="ABC09638006924340017;SOME_TEXT;SOME_OTHER_TEXT"
    echo $text | sed "s/^.\{8\}\(.\{8\}\).*/\1;&/"
    

    输出:

    00692434;ABC09638006924340017;SOME_TEXT;SOME_OTHER_TEXT
    

    由于您想在固定位置提取固定长度的子字符串,您也可以只使用 bash-builtins 来完成:

    text="ABC09638006924340017;SOME_TEXT;SOME_OTHER_TEXT"
    echo "${text:8:8};$text"
    

    【讨论】:

    • 谢谢 Ansgar,通过阅读 potong 的回答和您的我了解在这种情况下我的 sed 方法有多么错误(这里相当新手)。我知道有一个简单的解决方案可以关注,但不相信它会这么短:“;&”。
    • 工作得很好,谢谢。希望我不要通过发布我的最终 sed 字符串来破坏任何礼仪:sed -e 's/; /;/g;s/ ;/;/g;s/^.\{8\}\(.\{8\}\).*/\1;&/;s/^/'"$STRING"';/' $file > $TEMP$filecode``
    • s/; /;/g;s/ ;/;/g 可以简化为s/\s\+;\s\+/;/g,并且在结果前面加上$STRING 可以包含在第二个表达式中:s/^.\{8\}\(.\{8\}\).*/'"$STRING"';\1;&/(或使用-r 选项时的s/^.{8}(.{8}).*/'"$STRING"';\1;&/) .
    • 感谢您微调我的 sed 字符串。我正在使用 bash-builtins 从每个文件的第一行中提取 2 个固定长度的子字符串,这些子字符串成为我在处理所有行之前传递给 sed 的变量 $STRING(这些子字符串对于整个文件保持不变)。我在其余部分使用 sed,因为我认为比使用 bash-builtins 更快或更可靠。根据您的经验,请问我对性能的断言是否错误?
    • 不,sed 应该快一点。
    【解决方案2】:

    这对你有用(GNU sed):

    sed -r 's/^.{8}(.{8})/\1;&/' file
    

    【讨论】:

    • 谢谢你,我会在我的脚本中尝试一下,然后告诉你。
    猜你喜欢
    • 2021-08-19
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 2011-11-01
    相关资源
    最近更新 更多