2012-06-15 122 views
0

我放在一起这个shell脚本做两件事情:爆炸到阵列

  1. 变化(在这种情况下,“::”到“”)在数据文件中的分隔符
  2. 选择列我想要将它们追加到一个新文件中

它的工作原理,但我想要一个更好的方法来做到这一点。我特别想找到一种将每行分解为数组的另一种方法。使用命令行参数似乎不是要走的路。任何评论欢迎。

# Takes :: separated file as 1st parameters 
    SOURCE=$1 

    # create csv target file 
    TARGET=${SOURCE/dat/csv} 
    touch $TARGET 

    echo #userId,itemId > $TARGET 

    IFS="," 
    while read LINE 
    do 
     # Replaces all matches of :: with a , 
     CSV_LINE=${LINE//::/,} 
     set -- $CSV_LINE 
     echo "$1,$2" >> $TARGET 
    done < $SOURCE 
+0

有一定是更好的标题 - 请更新您的标题,因此是相关的。 (现在为-1,因为前面提到的原因,但稍后可以很容易地修改) – 2012-06-15 03:35:46

+1

将重定向放在循环外部的'$ TARGET',可能是'> $ TARGET'。然后你可以在循环之前丢失'touch'。您的标题行也需要包含引号('echo“#userID,itemId”')。 –

回答

2

相反的set,你可以使用阵列:

arr=($CSV_LINE) 
echo "${arr[0]},${arr[1]}" 
1

Perl可能有一个班轮做它。

Awk也可以轻松地做到这一点。

我的第一反应是AWK的组合和sed:

  • 桑达的分隔符
  • awk中转化来处理特定的列
cat inputfile | sed -e 's/::/,/g' | awk -F, '{print $1, $2}' 
# Or to avoid a UUOC award (and prolong the life of your keyboard by 3 characters 
sed -e 's/::/,/g' inputfile | awk -F, '{print $1, $2}' 
+1

请注意[UUOC Award](http://partmaps.org/era/unix/award.html)。 –

+0

公平评论 - 从来不知道我可以得到它的奖励;-) – John3136

+0

我将不得不在sed和awk上找到教程。感谢这个例子。 – contrapositive

1

awk确实是这里的工作的正确工具,它是一个简单的单线程。

$ cat test.in 
a::b::c 
d::e::f 
g::h::i 
$ awk -F:: -v OFS=, '{$1=$1;print;print $2,$3 >> "altfile"}' test.in 
a,b,c 
d,e,f 
g,h,i 
$ cat altfile 
b,c 
e,f 
h,i 
$ 
2

下面将从infile.dat打印列1和2。用 替换您想要的编号列的逗号分隔列表。

awk 'BEGIN { IFS='::'; OFS=","; } { print $1, $2 }' infile.dat > infile.csv