【问题标题】:Insert a string/number into a specific cell of a csv file将字符串/数字插入 csv 文件的特定单元格
【发布时间】:2014-02-20 12:40:23
【问题描述】:

基本上现在我有一个运行一系列测试的 for 循环。测试通过后,我将结果输入到 csv 文件中:

for (( some statement ))
     do
         if[[ something ]]
              input this value into a specific row and column
         fi
     done

我现在想不通的是如何将特定值输入到 csv 文件中的特定单元格中。我知道在awk 中,您可以使用以下命令读取单元格: awk -v "row=2" -F'@' 'NR == row { print $2 }' some.csv 这将打印第二行第二列中的单元格。我需要类似的东西,除了它可以将一个值输入到特定的单元格而不是读取它。有这样的功能吗?

【问题讨论】:

  • 使用那个 awk 并输出到另一个文件怎么样?
  • 我认为这将花费太长时间...我正在处理包含大约 1000 个条目的 csv 文件...每次我觉得有点忙时重新创建文件...加上这个文件会不断更新
  • 您也可以考虑为此使用sed -i。如果您粘贴一些示例输入,我们可以提供一些解决方案。它只是逗号分隔还是@
  • 它只用@分隔。我一直在玩 awk...到目前为止,我想出的是:awk -F, '{$(NF+1)=hi;}1' OFS=@ test.csv > output.csv 但是这只是用“hi”替换了最后一列,不知何故我也需要指定行
  • 首先获取所有要更改的值,然后一次性完成所有文件更新可能是有意义的。否则,您将多次打开和读取该文件,这可能对您的用例产生影响,也可能不产生影响。

标签: perl bash csv sed awk


【解决方案1】:

您可以使用以下内容:

awk -v value=$value -v row=$row -v col=$col 'BEGIN{FS=OFS="@"} NR==row {$col=value}1' file

并设置 bash 值 $value$row$col。然后你可以重定向并移动到原来的:

awk ... 文件 > new_file && mv new_file 文件

这个&&表示只要第一个命令(awk...)执行成功,就会执行第二个。

说明

  • -v value=$value -v row=$row -v col=$col 将 bash 变量传递给 awk。注意valuerowcol 可以是其他名称,我只是使用与 bash 相同的名称以便于理解。
  • BEGIN{FS=OFS="@"} 将字段分隔符和输出字段分隔符设置为 @OFS="@" 在这里不是必需的,但在你做一些print 时会很有用。
  • NR==row {$col=value} 当记录数(此处为行数)等于row 时,将col 列设置为value 值。
  • 1 执行默认的awk 操作:{print $0}

示例

$ cat a
hello@how@are@you
i@am@fine@thanks
hoho@haha@hehe

$ row=2
$ col=3
$ value="XXX"
$ awk -v value=$value -v row=$row -v col=$col 'BEGIN{FS=OFS="@"} NR==row {$col=value}1' a
hello@how@are@you
i@am@XXX@thanks
hoho@haha@hehe

【讨论】:

  • 你先生,太棒了!我已经研究这个问题很长时间了。感谢您的意见!
  • 如果你不介意我问 BEGIN{FS=OFS=...} 的目的是什么,通常我只看到其中一个被使用但不是同时使用跨度>
【解决方案2】:

您的问题有一个“perl”标签,所以这是一种使用Tie::Array::CSV 的方法,它允许您将 CSV 文件视为数组数组并使用标准数组操作:

use strict;
use warnings;

use Tie::Array::CSV;

my $row = 2;
my $col = 3;
my $value = 'value';

my $filename = '/path/to/file.csv';
tie my @file, 'Tie::Array::CSV', $filename, sep_char => '@';
$file[$row][$col] = $value;
untie @file;

【讨论】:

    【解决方案3】:

    使用 sed

    row=2                                        # define the row number
    col=3                                        # define the column number
    value="value"                                # define the value you need change.
    sed "$row s/[^@]\{1,\}/$value/$col" file.csv # use shell variable in sed to find row number first, then replace any word between @, and only replace the nominate column.
    # So above sed command is converted to sed "2 s/[^@]\{1,\}/value/3" file.csv
    

    如果上面的命令没问题,并且你的sed命令支持选项-i,那么运行命令直接更改file.csv中的内容

    sed -i "$row s/[^@]\{1,\}/$value/$col" file.csv
    

    否则,你需要导出到临时文件,并改回名称。

    sed "$row s/[^@]\{1,\}/$value/$col" file.csv > temp.csv
    mv temp.csv file.csv
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-18
      • 1970-01-01
      • 1970-01-01
      • 2017-08-03
      相关资源
      最近更新 更多