我有 Unix 脚本问题

我有 Unix 脚本问题

输入 - -

System:root,bin,user,saaa

显示输出----

System,root
System,bin
System,user
System,says

如何获得这个输出?

答案1

我建议您使用perl,但由于您指定了 shell 脚本...

第 1 步:根据角色将台词分成两部分:。使用cut命令或${parameter#word}and${parameter%word}结构。

步骤 2:根据角色将行的第二部分分成多个部分,。使用该awk命令 - 它应该告诉您您将拥有多少块(我不是专家awk,所以我不确定这是否会按照我设想的方式工作。)

步骤 3:循环浏览步骤 2 中获得的各个部件,将它们附加到步骤 1 中的第一个部件上,然后打印。

答案2

如果我们可以假设您的输入行恰好包含一个冒号 ( :),,冒号之前不能出现逗号 ( ),并且逗号和冒号都不能成为提取的子字符串的一部分(甚至没有转义),那么一个简单的awk脚本可能是足够的:

$ printf '%s\n' 'System:one,two,three' |
    awk -v FS=':|,' '{ for (i=2;i<=NF;i++) { print $1","$i } }'

输出:

System,one
System,two
System,three

字段分隔符FS是一个扩展的正则表达式,它将在每个字符:或上进行分割,


相反,如果您想要选择第一个冒号(可能包括逗号)之前的所有内容作为第一个输出字段,并在任何逗号处分割任何输入行的其余部分(假设没有逗号打算保留为任何的一部分)子字符串(甚至没有转义)),您可以求助于 shell 功能,如中所建议的海米的回答:

$ printf '%s\n' 'System:one,two,three' |
    while IFS= read -r rem; do      # IFS= to preserve blank characters
      first=${rem%%:*}              # Remove from the first ':' on
      rem=${rem#"$first"}           # Remove first from the beginning of rem
      rem=${rem#:}                  # Strip the remaining ':' at rem's beginning
      while test "$rem"; do         # Exit when rem is empty
          second=${rem%%,*}         # Remove from the first ',' on
          rem=${rem#"$second"}      # Remove second from the beginning of rem
          rem=${rem#,}              # Strip the remaining ',' at rem's beginning
          printf '%s\n' "$first,$second"
      done
    done

只要确保您理解使用 shell 循环处理文本的注意事项

或者,使用 GNU sed

$ printf '%s\n' 'System:one,two,three' |
sed -n '
  :l1
    s/^[^:]*:\n//g;
    t l2;
  s/^\([^:]\{1,\}\):\([^,\n]\{1,\}\)*,\{0,1\}\(.*\)$/\1:\3\n\1,\2/;
    t l1;
  q;
  :l2 p;
'

这里,分支 ( t) 到标签 ( l1) 用于通过循环处理每一行输入。一次一个,第一个:和第一个后续之间的子字符串,作为新行附加到模式空间,并连接在第一个之前的子字符串之后:。当没有更多的子字符串可提取时,原始字符串的剩余部分将被删除,模式空间将被打印并且程序退出。

(对于 GNUsed版本 >= 4.6,您可以通过使用选项调用它来逐步查看正在发生的情况--debug)。

请注意,使用\n内部括号表达式来匹配(此处为否定匹配)<newline>字符是非标准的:POSIX 规定<backslash>在该上下文中将失去任何特殊含义。

相关内容