2013-03-01 79 views
3

我有一个文本文件,可以有X个字段,每个字段用逗号分隔。在我的脚本中,我逐行阅读,检查该行上已填充了多少个字段,并确定需要将多少个逗号附加到该行的末尾来表示所有字段。例如,一个文件是这样的:bash:逐行读取文件并sed追加

Address,nbItems,item1,item2,item3,item4,item5,item6,item7  
2325988023,7,1,2,3,4,5,6,7 
2327036284,5,1,2,3,4,5 
2326168436,4,1,2,3,4 

应该成为这样的:

Address,nbItems,item1,item2,item3,item4,item5,item6,item7 
2325988023,7,1,2,3,4,5,6,7 
2327036284,5,1,2,3,4,5,, 
2326168436,4,1,2,3,4,,, 

我下面的作品脚本,但似乎非常低效的。逐行阅读是否对大文件有困难?这是导致经济放缓的sed吗?更好的方式来做到这一点?

#!/bin/bash 

lineNum=0 
numFields=`head -1 File.txt | egrep -o "," | wc -l` 

cat File.txt | while read LINE 
do 
     lineNum=`expr 1 + $lineNum` 
     num=`echo $LINE | egrep -o "," | wc -l` 
     needed=$((numFields - num)) 
     for ((i=0 ; i < $needed ; i++)) 
     do 
       sed -i "${lineNum}s/$/,/" File.txt 
     done 
done 

回答

11

这种类型的事情是一个像awk语言通常是最好的做法,例如:

awk 'NR==1{n=NF}{$n=$n}1' FS=, OFS=, file 
+1

+1 Nice! ..... – Kent 2013-03-01 16:12:19

+0

哇,非常感谢。它不仅完美达到我的目标,而且简单而快速! – ssbsts 2013-03-01 23:42:26

+0

+1一如既往的Scrutinizer优雅的解决方案, - Akshay – 2014-02-20 18:02:43

0

这里是一个完整的解决方案bash

(
    IFS="," 
    read hdrLine 
    echo "$hdrLine" 
    read -a header <<< "$hdrLine" 
    numFields="${#header[@]}" 

    while read -a line; do 
     pad=${#line[@]} 
     while ((pad < numFields)); do 
      line[pad++]= 
     done 
     echo "${line[*]}" 
    done 
) <File.txt> newFile.txt 
mv newFile.txt File.txt 

awk解决方案是好得多;这最好看作bash演示。

+0

感谢您的输入,但它实际上并没有达到我的目标。从我所知道的情况来看,即使没有必要,也只会在每一行附加一个逗号,即所有字段已经占了。 – ssbsts 2013-03-01 23:44:00

+0

这就是我没有先测试的结果。如果你分配给一个更大的索引,我最近读不出宣布该数组将填充中间插槽。我想知道我在想什么,因为它肯定不会是'bash'!我会留下这个答案一下,看看我是否可以挽救它;否则我会删除。 – chepner 2013-03-01 23:52:58