如何使用 bash 增加客户端 Seat_num?我有这个文件:
$ cat test
client1
name="", possition="", seat_num=""
client2
name="", possition="", seat_num=""
我需要这种增量:
client1
name="", possition="", seat_num="1"
client2
name="", possition="", seat_num="2"
我尝试了这种方法,但它没有达到我想要的效果:
$ while read -r line; do i=1;echo $line|sed -e 's/seat_num=""/seat_num="$i"/';((i++)); done <<< "$(grep -A 2 client test)"
client1
name="", possition="", seat_num="$i"
client2
name="", possition="", seat_num="$i"
答案1
使用awk
:
awk 'BEGIN{FS=OFS="\""} /seat_num=/{$6=++n}1' test
FS=OFS="\""
将输入和输出字段分隔符设置为"
。- 如果
seat_num=
在一行中找到 ,则将第 6 个字段更改为++n
。 var=++n
意思是先递增n
,后设置var
。相比之下,之后var=n++
会设置var
并增加。中未定义的变量awk
的值为0
,因此您需要先递增 (-->++n
)。
要就地编辑文件,您可以使用(-i inplace
如果可用)。
如果不可用,请添加> test.tmp && mv test.tmp test
答案2
尽管您的问题指定了“递增”(添加到现有数字,通常加 1),但我从阅读您的其他评论中得到的印象是,您真的很想遍历文件中的客户端并读取“客户端”之后的数字" 在一行中,然后使下一行中的 Seat_num 等于相同的数字。
如果是这种情况,那么以下 sed 命令对我有用,其中 test 的内容与问题中的内容相同。 (我确信还有很多其他方法可以做到这一点):
sed 'H;1h;$!d;x; s/client\([0-9]*\)\(\n[^\n]*\)seat_num=""/client\1\2seat_num="\1"/g' <<< cat test
这从 @Wiktor Stribizew 的回答中的一个神奇字符串开始这个问题:“(H;1h;$!d;x;
将文件放入内存)”。阅读手册页,我认为它将将从输入读取的模式行复制到“保持空间”中,然后删除该模式并从输入中读取另一行模式,直到输入结束,然后交换“保持空间” ”回到“模式空间”准备运行以下替换。然而,我仍然不清楚细节,所以我很乐意纠正。
在替换中,我们查找client
后跟 0 个或多个数字 ( [0-9]*
),并使用转义括号\(
并\)
记住这些数字。然后我们寻找一个换行符,后跟 0 个或多个非换行符(这样我们只能读取到下一个seat_num
),然后是下一个seat_num=""
- 再次使用转义括号来记住 之前的内容seat_num=
。
client
我们用原始文本和记住的数字(使用第一个记住的参数)替换所有这些,\1
然后是第二个记住的参数,然后是原始seat_num="
文本和第一个记住的参数的重复(后面的数字)client
和最后的"
。由于该模式现在包含整个文件,因此我们使用该g
命令在全局范围内进行此替换。
答案3
seat_num
开始1
。
你可以试试:
i=1
while IFS= read -r line; do
if grep -Fq 'seat_num=""' <<< "$line"; then
sed "s/seat_num=\"\"/seat_num=\"$((i++))\"/" <<< "$line"
else
printf '%s\n' "$line"
fi
done <<< "$(grep -A 2 client test)"
输出:
client1
name="", possition="", seat_num="1"
client2
name="", possition="", seat_num="2"
i
如果行包含 则递增seat_num=""
。