awk / sed循环CSV - 将子项绑定到第1列

时间:2013-04-03 16:15:33

标签: linux bash sed awk

应Charles Duffy的要求重新设计,重点更为狭窄。

我的CSV文件如下所示:

Security Policy: Blahblahblah,,,,,,,,,
12,,host_A,net-B,https,drop,Log,Any,Any,comments
13,,host_A,net-B,smtp,drop,Log,Any,Any,comments
14,,host_A,net-B,http,accept,Log,Any,Any,comments 
,,net-C,,,,,,,
,,net-D,,,,,,,
15,,host_A,net-B,http,accept,Log,Any,Any,comments
,,host_B,net-C,service_X,,,,,
,,host_C,net-D,service_y,,,,,
,,host_D,,,,,,,
,,host_E,,,,,,,

我需要分别解析每个值,但是我需要在各自的语句中包含$ 1。正如您所看到的,这对13&然而,当它们的列是空白的(儿童)时,14和15会成为一个严重的问题。

循环使用它的最佳方式是什么?

例如,我希望输出看起来像:

'text goes here' $1 'more text' $3 'more text'
'text goes here' $1 'more text' $4 'more text'

使用实际值(15):

'text goes here' 15 'more text' host_A 'more text'
'text goes here' 15 'more text' host_B 'more text'
'text goes here' 15 'more text' host_C 'more text'
'text goes here' 15 'more text' host_D 'more text'
'text goes here' 15 'more text' host_E 'more text'
'text goes here' 15 'other text' net-B 'more text'
'text goes here' 15 'other text' net-C 'more text'
'text goes here' 15 'other text' net-D 'more text'
'text goes here' 15 'text' http 'more text'
'text goes here' 15 'text' service_X 'more text'
'text goes here' 15 'text' service_y'more text'

等等。

谢谢,

2 个答案:

答案 0 :(得分:1)

process_file() {
  # declare local variables
  declare -a last_seen row
  declare col_idx col

  read # discard first line

  while IFS=, read -r -a row; do
    # for each remaining line...
    for col_idx in "${!row[@]}"; do
      # update last-seen rows with any contents here
      col=${row[$col_idx]}
      if [[ $col ]]; then
        last_seen[$col_idx]=$col
      fi
    done

    # ...and operate on those values.
    printf 'text goes here %s more text %s more text\n' \
      "${last_seen[0]}" "${last_seen[2]}" "${last_seen[3]}"
  done
}

process_file <input.csv >output.txt

答案 1 :(得分:1)

我真的在猜测,因为你的问题没有解释你想要什么,但是你正在寻找的是这样的:

$ cat file
Security Policy: Blahblahblah,,,,,,,,,
12,,host_A,net-B,https,drop,Log,Any,Any,comments
13,,host_A,net-B,smtp,drop,Log,Any,Any,comments
14,,host_A,net-B,http,accept,Log,Any,Any,comments
,,net-C,,,,,,,
,,net-D,,,,,,,
15,,host_A,net-B,http,accept,Log,Any,Any,comments
,,host_B,net-C,service_X,,,,,
,,host_C,net-D,service_y,,,,,
,,host_D,,,,,,,
,,host_E,,,,,,,

$ awk -f tst.awk file
12  host_A net-B https drop Log Any Any comments
13  host_A net-B smtp drop Log Any Any comments
14  host_A net-B http accept Log Any Any comments
14  net-C net-B http accept Log Any Any comments
14  net-D net-B http accept Log Any Any comments
15  host_A net-B http accept Log Any Any comments
15  host_B net-C service_X accept Log Any Any comments
15  host_C net-D service_y accept Log Any Any comments
15  host_D net-B http accept Log Any Any comments
15  host_E net-B http accept Log Any Any comments

$ cat tst.awk
BEGIN{ FS="," }
NR==1 { next }
$1 != "" { split($0,dflt) }
{ for (i=1;i<=NF;i++) if ($i == "") $i = dflt[i]; print }