【问题标题】:How to replace string with bash script and write back the Result如何用 bash 脚本替换字符串并写回结果
【发布时间】:2013-11-09 21:21:01
【问题描述】:

有一个 CSV 文件有一些列,第一列是 5 位客户编号,其他列用“;”分隔

这是一个例子:

12345;some;other;cols;comes;here
;some;other;cols;comes;here
;some;other;cols;comes;here
67890;some;other;cols;comes;here
34567;some;other;cols;comes;here
;some;other;cols;comes;here
;some;other;cols;comes;here
;some;other;cols;comes;here
;some;other;cols;comes;here
24315;some;other;cols;comes;here

如果第一列是空的,我需要设置最后一个给定的客户 ID。结果应如下所示:

12345;some;other;cols;comes;here
12345;some;other;cols;comes;here
12345;some;other;cols;comes;here
67890;some;other;cols;comes;here
34567;some;other;cols;comes;here
34567;some;other;cols;comes;here
34567;some;other;cols;comes;here
34567;some;other;cols;comes;here
34567;some;other;cols;comes;here
24315;some;other;cols;comes;here

现在我使用 bash 脚本逐行读取文件,并想检查该行是否以数字开头。如果是,则用“;”爆炸该行并使用 array[0] (第一个值)设置 customerID。接下来,我检查该行是否不是以数字开头,并想在该行的开头写五个数字。但我无法使用客户 ID 访问数组索引。

这是我的脚本:

#!/bin/bash
while read line
do
    row=$line
    if echo $row |grep "^[0-9].*$" > /dev/null;
      then
        arr=$(echo $row | tr ";" "\n")
        echo ${arr[0]};
    fi
done < $1

我得到整行没有“;”而不是作为 arr[0] 的 CustomerID 接下来我不知道如何将行首的数字写回文件。有人可以帮帮我吗?

【问题讨论】:

    标签: linux bash csv


    【解决方案1】:

    试试:

    awk -v id=12345 -F ';' '$1==""{$1=id;} {id=$1; print}'  OFS=';' file
    
    • awk 使用字段分隔符;,这使您可以以$1$2$3 等方式访问每个单独的字段。
    • -v id=12345 是您传递给 awk 以在第一个字段为空时使用的命令行参数
    • $1="" 是检查第一个字段是否为空的条件
    • $1=id$1 设置为传递的变量 id
    • {id=$1; print} 设置 id 变量用于下一行,然后打印该行

    输出:

    12345;some;other;cols;comes;here
    12345;some;other;cols;comes;here
    12345;some;other;cols;comes;here
    67890;some;other;cols;comes;here
    34567;some;other;cols;comes;here
    34567;some;other;cols;comes;here
    34567;some;other;cols;comes;here
    34567;some;other;cols;comes;here
    34567;some;other;cols;comes;here
    24315;some;other;cols;comes;here
    

    【讨论】:

    • 我在问题中添加了一个示例。你能解释一下我可以在脚本中实现它的 awk 命令吗?
    • 感谢您的帮助,但 ID 不固定。空字符串应替换为最后给定的 ID。
    • 是的,我知道,awk 命令并没有修复它,它总是使用id=$1; 用前一行的customer id 覆盖id。当第一行第一列为空时,我正在传递 id。
    • 好吧,我误解了命令,好吧,但在所有更正的行中,没有“;”
    【解决方案2】:

    纯 bash 解决方案:

    #!/bin/bash
    # Globally set IFS, if you don't like it, wrap it all in a subshell.
    IFS=';'
    lastID=-1
    while read -a row; do
        [[ -z ${row[0]} ]] && row[0]=$lastID
        lastID=${row[0]}
        # Abusing IFS
        echo "${row[*]}"
    done < "$1"
    

    【讨论】:

      猜你喜欢
      • 2022-07-21
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      相关资源
      最近更新 更多