【问题标题】:How to increment and decrement values in a csv from shell如何从shell增加和减少csv中的值
【发布时间】:2011-12-04 16:30:42
【问题描述】:

我有一个 csv 文件,比如 table.csv

foo;3
bar;1

还有一个脚本

#!/bin/bash
[..]
# increment ${searchterm} by one
eval [..]
# decrement ${searchterm} by one

我的问题是用递增的整数替换正确的行和值。另外:如果文件中没有搜索词,则假定为0。

目标是对不同评估语句中的进程数量进行机器可读的概述。

awk 或 sed 可能是解决方案,但我没有找到线索。

编辑:嗨,@shellter 的回答已经解决了我的问题,我只是试图让文档更精确。 使用输入“foo”我想递增到

foo;4
bar;1

在运行评估语句后返回原始值。 随着“演示”的输入,我想得到一个输出像

foo;3
bar;1
demo;1

然后返回

foo;3
bar;1
demo;0

后记。

背后的想法是让整个脚本同时在多个实例中运行,并且能够从 table.csv 中读取实例的数量。

【问题讨论】:

  • 你能用预期的输出解释一下吗?

标签: shell csv awk


【解决方案1】:

鉴于您的数据和您的稀疏描述(显示您需要/期望的输出以及您收到的任何错误消息,总是很好),试试这个

cat myData
foo;3
bar;1

cat myFixer.sh
#!/bin/bash
awk '
  BEGIN {FS=";" ; OFS=";"}
  {
     if ($1 == target ) {
       $2 += incr
       targFound=1
     }
     print $0
  }
  END { 
    if (! ( targFound) ) {
      print target OFS "0"
    }
  }'  target="foo" incr=3 myData

 # output
 foo;6
 bar;1

 foo;3
 bar;1
 BAD;0

我使用incr=3 来表明这是一个通用解决方案。如果您需要 +1 增量,只需将参数更改为 incr=1

一些 awk 希望看到命令行变量设置为 -v target=foo -v incr=3

您可以轻松更改此 bash 脚本以接受目标和 incr 的参数,输入文件为 $1 $2 $3。

现在输出刚刚出现在您的屏幕上。我建议您将输出重定向到新文件。

myFixer.sh > myData.New 

请注意,FS 是 awk 的特殊 var,表示 FieldSeparator。 OFS 是 OutputFieldSeparator,因此可以通过将 OFS 更改为 OFS=","

Awk 将每一行输入解析为字段;整行称为 $0,而由 FS 分隔的每个元素(在您的情况下为“;”)分配一个从左到右移动的序列号,因此第一个字段称为 $1,第二个字段称为 $2,等等。 .awk还有很多其他的内部变量,包括NF(Number_of_Fields),它是为读取的每一行数据设置的。您可以单独使用 NF 来验证您在一行中拥有正确数量的字段(例如),或者您可以使用 '$' 字符“取消引用” NF 的值,并可以访问每行的最后一个值'$NF'。例如,我们可以将 $2 重写为 $NF。

在 { .. } 块中给定代码的 awk 的默认操作是读取输入的每一行,然后按照块内逻辑的指示对其进行处理。在您的情况下,我们查看字段一以查看它是否是目标字符串,如果是,我们增加那里的值。

对于所有记录,我们打印出完整的行,无论它是否增加了。

在读取输入文件中的任何记录之前执行 BEGIN 代码块,这是发生变量初始化的一种方式(或者在这种情况下,您将覆盖 FS 的默认值)。

在读取所有输入文件后执行 END 块。由于您需要打印 foo;0 如果它不存在,我们会保留一个标志来指示您的搜索目标是否已找到。我们要做的最后一件事是检查是否找到了目标,如果没有找到,则发出一行带有“目标 OFS 0”的文本。

我希望这会有所帮助。

附言

欢迎使用 StackOverflow,请让我提醒您我们通常在这里做的三件事:1) 当您获得帮助时,请尝试提供帮助,回答您专业领域的问题 2) 阅读常见问题解答,http://tinyurl.com/2vycnvr,3 ) 当您看到好的问答时,请使用灰色三角形 http://i.imgur.com/kygEP.png 给他们投票,因为系统的可信度是基于用户通过分享他们的知识而获得的声誉。还记得通过点击复选标记http://i.imgur.com/uqJeW.png 来接受更好地解决您的问题的答案(如果有)

【讨论】:

  • 嗨,谢谢你这么长的回答。它有很大帮助!这正是我正在寻找的。请原谅我不清楚的问题。
  • 对不起,我正在编辑,电话响了。我已经标记了您的解决方案。
  • 太好了,很抱歉成为老马!谢谢!
猜你喜欢
  • 2015-01-29
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多