how to iterate though delimited values in bash

后端 未结 3 1966
攒了一身酷
攒了一身酷 2021-01-28 17:41

BASH

input: cat test

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

desired output is:

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


        
相关标签:
3条回答
  • 2021-01-28 18:03

    Solution 1st: Could you please try following.

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

    Solution 2nd: Adding another awk too now.

    awk '{gsub(/;/,ORS $1 OFS)} 1'  Input_file
    
    0 讨论(0)
  • 2021-01-28 18:15

    Straightforward shell:

    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" 
    

    Clever shell, if first column never contains percent or backslash:

    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
    

    Both of these leave IFS and (maybe) noglob changed; if this is all or the last part of a script, or a function using (), those changes are to a local instance and discarded. Otherwise either explicitly save and restore, or surround with () so they are discarded.

    Similarly both clobber the positional arguments, which generally matters only when in a script or function; if those are needed subsequently, save and restore them, or alternatively in bash or ksh only use a separate explicit array variable:

    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
    
    0 讨论(0)
  • 2021-01-28 18:20

    This might work for you (GNU sed):

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

    Replace each ; by a newline followed by the key.

    0 讨论(0)
提交回复
热议问题