2012-07-03 88 views
1

我试图使用某些列宽打印CSV文件。我认为我有一个错误,导致第一列不能打印。正如你所看到的,我是新来bash和拼命试图使它像C.Bash - 打印CSV文件

CSV='./test.csv' 
column_width=(20 6 5 10 10 10 10 8 30) 

IFS="," 
     while read LINE 
     do 
       set -- $LINE 
       arg=([email protected]) 
       for ((i = 0 ; i < ${#arg[@]} ; i++)) 
       do 
         case $i in 
           1) printf "%-20s" ${arg[$i]} ;; 
           2) printf "%-6s" ${arg[$i]} ;; 
           3) printf "%-5s" ${arg[$i]} ;; 
           4) printf "%-10s" ${arg[$i]} ;; 
           5) printf "%-10s" ${arg[$i]} ;; 
           6) printf "%-10s" ${arg[$i]} ;; 
           7) printf "%-10s" ${arg[$i]} ;; 
           8) printf "%-8s" ${arg[$i]} ;; 
           9) printf "%-30s\n" ${arg[$i]} ;; 
         esac 
       done 
     done < $CSV 
     unset IFS 

我也有麻烦转动case语句进入一个循环。无果,我试着用替换整个C风格的for循环:

for i in "${arg[@]}"; do 
     printf "%-${column_width[$i]}s" ${arg[$i]} 
done 

我敢肯定有一个更好的方式来做到这一点。我正在尝试学习sed/awk,但是现在我想知道如何在没有它们的情况下执行此操作。

+1

您的case语句不包括$ i == 0,因此跳过了第一列。 –

+0

谢谢。我可以更仔细地阅读。 – contrapositive

回答

2
#!/usr/bin/env bash 

csv=./test.csv 
column_width=(20 6 5 10 10 10 10 8 30) 

while n=0; IFS=, read -ra x; do 
    printf '%-*s' {,,,,,,,,}{"${column_width[n]}","${x[n++]}"} 1 $'\n' 
done <"$csv" 
+0

+1,尽管类似Perl的不可理解性。 :)尽管如此,您需要为每次迭代将'n'重置为0。 – chepner

+0

@chepner谢谢修复。可能很好,我没有显示处理每行不同数量字段的版本。 :) – ormaaj

+0

这正是我所寻找的;一些简洁。它看起来像内置的bash命令的一个很好的使用(虽然我可能不会认识到糟糕的用途)。请随意发布不同领域的版本。 – contrapositive

2

我觉得剧本很优雅。你会很难做到这一点在任何语言更简洁(虽然这使用我不喜欢的bashisms: - >)

因为我更多的避免脚本逻辑和使用您的 - 编者的宏观功能的一面,这里将是我的版本。

#!/bin/sh 

CSV='./test.csv' 

while IFS=, read one two three four five six seven eight nine 
do 
    test "$one" && printf %s-20s "$one" 
    test "$two" && printf %s-6s "$two" 
    test "$three" && printf %s-5s "$three" 
    test "$four" && printf %s-10s "$four" 
    test "$five" && printf %s-10s "$five" 
    test "$six" && printf %s-10s "$six" 
    test "$seven" && printf %s-10s "$seven" 
    test "$eight" && printf %s-8s "$eight" 
    test "$nine" && printf %s-30s "$nine" 
    printf \\n 
done < "$CSV" # mind the quoting 

我个人认为这是一个更愉快的眼睛(而不是bashisms!),但YMMV。我也避免了大量的测试,只是尽可能地打印出来。

+0

这比ormaaj的简洁版本更具可读性,然而,“bashisms”正是我试图学习的东西。 :) – contrapositive

+0

我知道我不会告诉你什么时候我认为你问的是错误的答案或错误的问题,但我认为你真的应该想出一个问题,用简单的'sh'-样式。当你创建这样一个例子时,你可能会注意到它在bash中也会非常繁琐;-)。对不起,我很抱歉。 –

1

好的工作,对立的。

脚本中的偏移错误是因为即使在Bash中数组索引从0开始,而您的开关案例不会。我能想到的最小变化是“移位”数组arg。尝试使用arg=(0 [email protected])。您可以在数组的第0个索引处使用任何其他值。不存在的情况下将被照顾。