Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从shell递增和递减csv中的值_Shell_Csv_Awk - Fatal编程技术网

如何从shell递增和递减csv中的值

如何从shell递增和递减csv中的值,shell,csv,awk,Shell,Csv,Awk,我有一个csv文件,比如table.csv foo;3 bar;1 还有剧本 #!/bin/bash [..] # increment ${searchterm} by one eval [..] # decrement ${searchterm} by one 我的问题是用递增的整数替换右边的行和值。此外:如果searchterm不在文件中,则应假定它为0 目标是对eval语句中不同进程的数量有一个机器可读的概述 awk或sed可能是解决方案,但我没有找到任何线索 编辑:您好,由于@She

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

foo;3
bar;1
还有剧本

#!/bin/bash
[..]
# increment ${searchterm} by one
eval [..]
# decrement ${searchterm} by one
我的问题是用递增的整数替换右边的行和值。此外:如果searchterm不在文件中,则应假定它为0

目标是对eval语句中不同进程的数量有一个机器可读的概述

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

编辑:您好,由于@Sheller的答案已经解决了我的问题,我只想让文档更精确。 输入“foo”时,我希望增加到

foo;4
bar;1
运行eval语句后,返回原始值。 有了“demo”的输入,我想得到如下输出

foo;3
bar;1
demo;1
然后回到

foo;3
bar;1
demo;0
后记


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

给定您的数据和稀疏的描述(显示您需要/期望的输出和收到的任何错误消息总是很好),请尝试以下操作

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特殊变量,表示字段分隔符。OFS是OutputFieldSeparator,因此在您的情况下,通过将OFS更改为OFS=“,”可以轻松转换为真正的CSV

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

awk的默认操作(在{..}块中给定代码)是读取每一行输入,然后根据块内的逻辑对其进行处理。在您的例子中,我们查看字段1,看看它是否是目标字符串,如果是,我们在那里增加值

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

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

读取所有输入文件后执行结束块。因为你需要打印foo;0如果不存在,我们将保留一个标志以指示是否已找到您的搜索目标。我们要做的最后一件事是检查是否找到目标,如果没有,则发出一行“target of s 0”作为文本

我希望这有帮助

附言


欢迎来到StackOverflow,请让我提醒您我们通常在这里做的三件事:1)当您收到帮助时,尝试给予帮助,回答您专业领域的问题2)阅读常见问题解答,3)当您看到好的问答时,使用灰色三角形投票,因为系统的可信度是基于用户通过分享知识而获得的声誉。另外,请记住接受能更好地解决您的问题的答案,如果有的话,请按复选标记,

您能用预期的输出解释一下吗?您好,谢谢您的回答。这很有帮助!这正是我要找的。对不起,我的问题不清楚。对不起,电话铃响时我正在编辑。我已经标记了你的解决方案。太好了,对不起,我是个唠叨的人!谢谢