使用grep和sed代替一个字符串?

时间:2017-09-14 22:22:42

标签: bash sed find

我在编写bash时相当新,我对代码的错误/问题感到有些困惑。我有两个主要问题。如果P)我想看看是否存在某个文件。如果存在,我想使用balance更新newbalance

P) read -p "Enter email: " email
   read -p "Enter payment amount: " payment
   newbalance=$(echo $payment + $balance | bc)
   if [ -f $email ]; then
       sed -i "s/$balance/$newbalance/" $email
       #also tried
       #find . -type f -name "$email" -exec sed -i "s/${balance}{newbalance}/" {} \;
   else
       echo -e "Error: customer not found\n\n"
   fi
   balance=$newbalance
   continue
   ;;

当我尝试阅读payment 100.00时,我收到错误:

(standard_in) 2: syntax error
sed: -e expression #1, char 0: no previous regular expression

文件格式非常简单,余额只出现一次。

email  name
apt-XX rent balance duedate

当我重定向echo以修改文件时,代码工作正常。既然我已经尝试实施sed代码已停止工作,我不确定是什么导致了它。我已尝试将findsed一起使用,但这也不起作用。我查看了多个堆栈溢出问题,但示例与我的相似。

这是我处理

的文件之一
jboat@xyz.com John Boat
APT-5B 1100.00 100.00 2017-10-02

2 个答案:

答案 0 :(得分:0)

您可以使用bash进行计算,不需要bc。

newbalance=$((payment + balance))

sed命令没问题,你可能得到了错误,因为其中一个变量包含了废话。

答案 1 :(得分:0)

您收到该错误的最可能原因是$balance为空。例如:

$ echo 100.00 | sed 's//200.00/'
sed: -e expression #1, char 0: no previous regular expression

(回声就在那里因为sed无论如何都要求输入。)

因此,您需要跟踪$balance获取其价值的位置,并确保不会失败。

但是,由于它仍然容易出现故障,我建议使用AWK稍微更有弹性的方法:

awk -v newbalance="$newbalance" 'FNR==2 {$3=newbalance; print;}' "$email" > "$email.tmp" && mv "$email.tmp" "$email"

这将一个名为newbalance的awk变量设置为bash变量$newbalance的值,然后运行该脚本。 FNR告诉它要读取哪一行(在本例中为文件中的第二行),$3=newbalance将该行中第3个字段的值更改为我们之前传递的值。

最后的mv只是因为旧版本的awk无法编辑文件。请参阅:awk save modifications in place

请注意,如果你走下这个兔子洞,你可能最终会在完成之前用awk重写整个脚本。为了获得灵感,您可以将算法转移到awk本身:

awk -v payment="$payment" 'FNR==2 {$3+=payment; print;}' "$email" > "$email.tmp" && mv "$email.tmp" "$email"