我有一个csv文件,比如table.csv
foo;3
bar;1
和脚本
#!/bin/bash
[..]
# increment ${searchterm} by one
eval [..]
# decrement ${searchterm} by one
我的问题是用递增的整数替换右边的行和值。另外:如果searchterm不在文件中,则应假定为0。
目标是使用机器可读的概述不同eval语句中的进程数。
awk或sed可能是解决方案,但我没有找到线索。
编辑:嗨,因为@ shellter的答案已经解决了我的问题我只是试图让它更准确的文档。 输入“foo”我想增加到
foo;4
bar;1
并在运行eval语句后返回原始值。 随着“demo”的输入,我希望获得像
这样的输出foo;3
bar;1
demo;1
然后回到
foo;3
bar;1
demo;0
后记。
背后的想法是让整个脚本同时在多个实例中运行,并能够从table.csv中读取实例数。
答案 0 :(得分:0)
根据您的数据和稀疏描述(总是很好地显示您需要/期望的输出AND以及您获得的任何错误消息),试试这个
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
。
有些awks希望将命令行变量设置为-v target=foo -v incr=3
。
您可以轻松更改此bash脚本以接受目标和incr的参数,输入文件为$ 1 $ 2 $ 3.
现在输出刚出现在屏幕上。我建议您将输出重定向到新文件。
myFixer.sh > myData.New
请注意,FS是awk特殊var,表示FieldSeparator。 OFS是OutputFieldSeparator,因此可以通过将OFS更改为OFS =“,”
轻松转换为您的案例中的真实CSVAwk将每行输入解析为字段;整行被称为$ 0,而由FS(在你的情况下为';')分隔的每个元素被分配一个从左到右移动的序号,因此第一个字段称为$ 1,2nd为$ 2,等等。 .awk还有许多其他内部变量,包括NF(Number_of_Fields),它是为读取的每一行数据设置的。您可以单独使用NF来验证一行中是否有正确数量的字段(例如),或者您可以使用'$'字符“取消引用”NF的值,并且可以访问每行上的最后一个值'$ NF'。举个例子,我们可以将$ 2重写为$ NF。
给定{...}块中的代码的awk的默认操作是读取每行输入,然后按块内逻辑的指示处理它。在您的情况下,我们查看第一个字段以查看它是否是目标字符串,如果是,则在那里增加值。
对于所有记录,我们打印出完整的行,无论是否已增加。
在读取输入文件中的任何记录之前执行BEGIN代码块,这是一种进行变量初始化的方法(或者在这种情况下,您将覆盖FS的默认值)。
读取所有输入文件后执行END块。因为你需要打印foo;如果不存在,我们会保留一个标志来指示你的搜索目标是否已被找到。我们做的最后一件事是检查是否找到了目标,如果没有,则发出一行“目标OFS 0”作为文本。
我希望这会有所帮助。
P.S。
欢迎来到StackOverflow,请让我提醒您我们通常在这里做的三件事:1)在您收到帮助时,尽量给予帮助,在您的专业领域回答问题2)阅读常见问题解答,http://tinyurl.com/2vycnvr ,3)当你看到好的Q& A时,使用灰色三角形http://i.imgur.com/kygEP.png投票,因为系统的可信度是基于用户通过分享他们的知识而获得的声誉。还记得通过勾选复选标记http://i.imgur.com/uqJeW.png
来接受更好地解决问题的答案(如果有的话)