从 shell 脚本更新文件中的计数器

Updating counter in a file from shell script

我有一个 txt 文件,其中包含传输到 diff 远程机器的文件统计信息,如下所述

172.31.32.5 yes 2
172.31.32.6 yes 3

现在当另外 3 个文件传输到第一台机器时,我希望文件从 shell 脚本

更新到下面
172.31.32.5 yes 5
172.31.32.6 yes 3

我正打算使用这样的东西

sed -i '/$IP/d' /tmp/fileTrnsfr
echo "$IP yes $((oldcount + newcount))

但正在寻找更好的解决方案,可以使用 sed 或 awk 命令进行搜索、更新和替换

您可以使用 Awk 来实现。您需要将包含IP信息和文件数的变量导入context foAwk并修改

temp_file="$(mktemp)"
awk -v ip="$ip" -v count="$newcount" '==ip{$NF+=count}1' /tmp/fileTrnsfr > "$temp_file" && mv "$temp_file" /tmp/fileTrnsfr

mktemp用于创建一个临时名称,用于写入Awk的内容并将其移回原始文件名(模拟就地文件编辑)

以上内容适用于 Awk 的较旧的非 GNU 变体,它们不支持就地编辑。

在最新的 GNU Awk 中(因为 4.1.0 released), it has the option of "inplace" file editing:

[...] The "inplace" extension, built using the new facility, can be used to simulate the GNU "sed -i" feature. [...]

gawk -i inplace -v INPLACE_SUFFIX=.bak -v ip="$ip" -v count="$newcount" '==ip{$NF+=count}1' /tmp/fileTrnsfr 

这需要 GNU sed:

$ cat fileTrnsfr 
172.31.32.5 yes 2
172.31.32.6 yes 3

$ newcount=3
$ ip=172.31.32.5

$ sed -i -r '
    /^'"${ip//./\.}"'/ {
        s/(.*) ([[:digit:]]+)/printf "%s %d" "" "$(expr  + '"$newcount"')"/
        e
    }
' fileTrnsfr 

$ cat fileTrnsfr 
172.31.32.5 yes 5
172.31.32.6 yes 3

转换线

172.31.32.5 yes 2

进入

printf "%s %d" "172.31.32.5 yes" "$(expr 2 + 3)"

然后使用 e 命令将其作为命令执行(我相信使用 /bin/sh)

完全原生便携 POSIX shell:

#!/bin/sh

# read data from arguments (or else standard input), line by line
cat "${@:-/dev/stdin}" |while read line; do
  number="${line##*[^0-9]}"  # extract the number at the end of the line
  line="${line%$number}"     # remove that number from the end of the line
  echo "$line$((number+3))"  # append (number+3) to the end of the line
done