我想从 1000 开始增加端口号。我知道如何在使用此命令为所有端口分配编号时将它们设为 0
sed 's/port [0-9]\{1,5\}/port 0/g'
但不知道如何做相反的事情。我必须在多个脚本文件中更改 2k 行。
- 这就是我所拥有的
local-ip 155.165.170.10 port 0 remote-ip 155.16.241.11 port 3869 local-ip 155.165.170.10 port 0 remote-ip 155.16.241.11 port 3869 local-ip 155.165.170.10 port 0 remote-ip 155.16.241.11 port 3869 local-ip 155.165.170.10 port 0 remote-ip 155.16.241.11 port 3869
- 所需的输出如下所示:
local-ip 155.165.170.10 port 1000 remote-ip 155.16.241.11 port 3869 local-ip 155.165.170.10 port 1001 remote-ip 155.16.241.11 port 3869 local-ip 155.165.170.10 port 1002 remote-ip 155.16.241.11 port 3869 local-ip 155.165.170.10 port 1003 remote-ip 155.16.241.11 port 3869
答案1
您应该能够在以下位置执行此操作awk
:
awk 'BEGIN{p=1000} $1=="local-ip"{$4=p++} 1' input.cfg > output.cfg
这将解析所有以 开头的行local-ip
(作为防止空行或注释行的小安全措施),并将第四个字段(当前端口号)替换为从 1000 开始连续增加的数字。
更新
由于您在评论中声明要对多个文件执行此操作,因此可以使用以下 shell 循环:
for f in input{1..16}.cfg; do n=${f/input/output}; awk 'BEGIN{p=1000} $1=="local-ip"{$4=p++} 1' "$f" > "$n"; done
这将循环遍历所有匹配的文件input{1..16}.cfg
,将 替换input
为output
来生成输出 filename n
,并将awk
上述程序应用于每个输入/输出对。请注意,端口号将在文件本地重新编号,即每个文件在端口 1000 处重新启动。
答案2
使用 awk 相当简单。例如:
awk 'BEGIN { portno=1000 }
{ print $1, $2, $3, portno++, $5, $6, $7, $8 }' inputfile
这假设所有行的格式都如您的示例中所示。
答案3
k=1000
m=$(echo "$k\\";printf '%s' {0..9})
sed -En "
1{x;s/.*/$m/;x;}
/local-ip/!{p;d;}
G
s/(port )0( .*)\n(.*)\n.*/\1\3\2/
p;g;trst;:rst
# port+1
s/([0-8])(\n.*\1(.))/\3\2/;h;t
s/(9+)\n/_&/
:a;s/(_9*)9(0*\n)/\10\2/;ta
s/^_/0&/
s/(.)_(0+\n.*\1(.))/\3\2/
h
" file
输出:
local-ip 155.165.170.10 port 1000 remote-ip 155.16.241.11 port 3869
local-ip 155.165.170.10 port 1001 remote-ip 155.16.241.11 port 3869
local-ip 155.165.170.10 port 1002 remote-ip 155.16.241.11 port 3869
local-ip 155.165.170.10 port 1003 remote-ip 155.16.241.11 port 3869
为了增加 1,我们必须注意两件事。 lsd 是非 9 还是连续的 9。如果是前者,我们只需将 lsd 替换为其下一个更高的数字。如果是后者,我们将所有 lsd 9 更改为 0,并用下一个更高的数字替换邻居。然后存储回hold以供下一次迭代
答案4
你基本上有两个选择。
选项1:对每个输入文件运行 awk
# Loop over the input file numbers and run awk for each
for ((i=0; i<10; i++)); do awk '$1=="local-ip"{$4=1000+p++;}1' input$i.txt > output$i.txt; done
选项2:直接用awk创建输出文件
awk 'FNR==1{p=1000; sub("input", "output", FILENAME)} $1=="local-ip"{$4=p++} {print >> FILENAME}' input*.txt
如果您不想port 0
对每个输入文件重新开始,则只需运行 awk 一次(以便它知道当前的全局值)。或者NR==1{p=1000}
,您可以使用更简单的逻辑选项1:
awk 'FNR==1{sub("input", "output", FILENAME)} $1=="local-ip"{$4=1000+p++} {print >> FILENAME}' input*.txt