【问题标题】:how to iterate though delimited values in bash如何遍历bash中的分隔值
【发布时间】:2018-12-29 00:18:46
【问题描述】:

重击

输入:猫测试

  1 a;b;c;d
  2 a;b;c;d
  3 a;b;c;d

想要的输出是:

  1 a
  1 b
  1 c
  1 d
  2 a
  2 b
  2 c
  2 d
  3 a
  3 b
  3 c
  3 d 

这对程序员来说可能很简单。 谢谢。

【问题讨论】:

  • 听起来这是一个由两部分组成的问题。您应该在 bash 中搜索文件上的循环,其次,如何过滤每一行。做一点研究,尝试一些事情。在这里展示您已经尝试过的工作会有很长的路要走。
  • BashFAQ #1 是相当直接的,就作为迭代分隔值的字面指南而言。

标签: bash for-loop awk sed while-loop


【解决方案1】:

简单的外壳:

IFS=" ;"
shopt noglob # or set -f
while read -r line; do 
  set -- $line; a=$1; shift
  for b; do printf '%s %s\n' "$a" "$b"; done
done
# if data never contains backslash can omit -r from read
# if data never contains glob patterns (? * [..] etc) can omit set -f
# if data never contains backslash and first col never begins with hyphen
# can replace printf with echo "$a" "$b" 

聪明的shell,if第一列从不包含百分号或反斜杠:

IFS=" ;"
shopt noglob # or set -f
while read -r line; do 
  set -- $line; a=$1; shift
  printf "$a %s\n" "$@"
done
# read -r and set -f as above

这两个都使 IFS 和(也许)noglob 发生了变化;如果这是脚本的全部或最后一部分,或使用 () 的函数,则这些更改将针对本地实例并被丢弃。否则要么显式保存和恢复,要么用 () 括起来,这样它们就被丢弃了。

同样,它们都破坏了位置参数,这通常只在脚本或函数中才重要;如果随后需要这些,保存并恢复它们,或者在 bash 或 ksh 中仅使用单独的显式数组变量:

IFS=" ;"
shopt noglob # or set -f
while read -ra ary; do
  a=${ary[0]}; unset ary[0]
  for b in "${ary[@]}"; do printf '%s %s\n' "$a" "$b"; done
  # or 
  printf "$a %s\n" "${ary[@]}"
done

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -r 's/^((\s*\S+\s*)[^;]*);/\1\n\2/;P;D' file
    

    将每个 ; 替换为换行符,后跟键。

    【讨论】:

      【解决方案3】:

      解决方案一:请您尝试以下方法。

      awk -F'[ ;]' '{for(i=2;i<=NF;i++){print $1,$i}}' Input_file
      

      解决方案 2: 现在也添加另一个 awk

      awk '{gsub(/;/,ORS $1 OFS)} 1'  Input_file
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-05
        • 2017-07-07
        • 2014-10-02
        相关资源
        最近更新 更多