【问题标题】:bash: read file line by line and sed to appendbash:逐行读取文件并 sed 追加
【发布时间】:2013-02-16 04:30:47
【问题描述】:

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

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

【问题讨论】:

    标签: bash sed while-loop


    【解决方案1】:

    这类事情通常最好用awk之类的语言来完成,例如:

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

    【讨论】:

    • 哇,非常感谢。它不仅完美地实现了我的目标,而且非常简单和快速!
    • +1 Scrutinizer 一如既往的优雅解决方案——Akshay
    【解决方案2】:

    这是完整的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 演示。

    【讨论】:

    • 感谢您的输入,但它实际上并没有达到我的目标。据我所知,它只在每一行附加一个逗号,即使在没有必要的情况下,即所有字段都已被考虑在内。
    • 这就是我没有先测试的结果。我不能发誓我最近读到如果您分配给更大的索引,该数组将被中间插槽填充。我想知道我在想什么,因为它肯定不是bash!我会暂时保留这个答案,看看我是否可以挽救它;否则我会删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 2019-09-02
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多