【问题标题】:Using sed to extract string values使用 sed 提取字符串值
【发布时间】:2016-08-25 06:35:04
【问题描述】:

有人会如何使用 sed 来重新排序以逗号分隔的字符串中的子字符串组?

例如,

你好,鲍勃,我叫约瑟夫

变成:

约瑟夫,我叫,你好,鲍勃

【问题讨论】:

    标签: regex string unix sed


    【解决方案1】:

    以此作为测试文件:

    $ cat file
    hello bob, my name is, joseph
    

    我们可以根据需要对字段重新排序:

    $ sed -E 's/([^,]*), *([^,]*), *([^,]*)/\3, \2, \1/' file
    joseph, my name is, hello bob
    

    工作原理

    sed 替代命令的格式为 s/old/new/。这会将old 替换为new,其中old 是一个正则表达式。在这种情况下,old 是:

    ([^,]*), *([^,]*), *([^,]*)
    

    括号中的项目是组。这将行分成三个逗号分隔的组。我们可以将这三个组分别称为\1\2\3。那么,在new 文本中,我们使用:

    \3, \2, \1
    

    这会颠倒组的顺序,按照您的要求将第三个放在最后,将第一个放在最后。

    处理不定数量的列

    如果我们要反转所有子串但事先不知道子串的个数,那么awk是一个很好的工具:

    $ awk -F', *' '{for (i=NF;i>0;i--)printf "%s%s",$i,(i>1?", ":"\n")}' file
    joseph, my name is, hello bob
    

    -F', *' 表示我们希望使用逗号可选地后跟空格作为字段分隔符。

    for (i=NF;i>0;i--)printf "%s%s",$i,(i>1?", ":"\n") 在每个字段上反向循环并打印它,后跟,,或者最后一个换行符。

    反转子字符串中的单词

    这是一个在子字符串中反转单词的示例:

    $ sed -E 's/([^ ,]*) ([^,]*), /\2 \1, /' file
    bob hello, my name is, joseph
    

    这是一个反转子字符串中的单词同时也反转子字符串顺序的示例:

    $ sed -E 's/([^ ,]*) ([^,]*), *([^,]*), *([^,]*)/\4, \3, \2 \1/' file
    joseph, my name is, bob hello
    

    【讨论】:

    • 如果组的数量不定怎么办?
    • @KennyLau 在这种情况下,我会使用awk。请参阅 awk 代码的更新答案。
    • 谢谢!如果我想使用 sed 对同一组中的单词进行重新排序怎么办?
    • @user 好的。我也添加了一些例子。
    【解决方案2】:

    你也可以使用awk

    awk -F', ' '{ print $3 ", " $2 ", " $1 }' <<< "hello bob, my name is, joseph"
    #joseph, my name is, hello bob
    

    更新:
    基于@andlrc's的评论,这个解决方案更简单:

    awk 'BEGIN{FS=OFS=", "}{print $3, $2, $1}' <<< "hello bob, my name is, joseph"
    

    【讨论】:

    • 可以使用awk 'BEGIN{FS=OFS=", "}{print $3, $2, $1}',这样就不用硬编码, 3次了
    • 一直在学习......我会用你的评论更新我的答案,tks!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 2021-12-14
    • 2014-08-21
    • 1970-01-01
    相关资源
    最近更新 更多