使用 bash(sed 或 awk?)在特定位置插入计数
Insert counts at specific positions using bash (sed or awk?)
我有一个文件 (mirrorlist.pacnew
) 包含这样的镜像:
prakhar@inS4n3 ~ $ cat /etc/pacman.d/mirrorlist.pacnew
...
## Worldwide
#Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
#Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
## Australia
#Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
...
我应该选择镜像并取消注释。然而,一个工具 rankmirrors
为我确定了最好的镜像,所以我使用 sed
来 取消对所有镜像的注释 .
prakhar@inS4n3 ~ $ cat /etc/pacman.d/mirrorlist.pacnew | sed -r 's/^#([^#]+)/#\n/'
...
## Worldwide
#Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
#Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
## Australia
#Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
...
我保留注释行,因为 rankmirrors 打印它们并且我可以跟踪进度(它不打印它正在处理的未注释行)。
但是,我希望 sed
或 awk
在每行中打印 服务器计数和总计数 。
具体来说:
- 取消注释行,如我在上面给出的示例。
- 从原始文件打印当前#Server索引的索引(不是实际行号,因为文件包含县名,通用注释)。
最终输出看起来像这样:
#22/247 Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
Here 是完整文件的副本。
编辑:
我自己取得了一些进步,我将我的工作添加为,因为它实现了上述目标,但不是最优的。
将同一个文件传递给 awk 两次。第一关,算数。二传,替补。
awk 'NR==FNR {
if( /^#Server *=/)count++;
next;
}
/#Server *=/{
sub(/^#*/,"");
print "#" ++i "/" count " " [=10=];
}
1' serverlist serverlist
给出:
## Worldwide
#1/3 Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
#2/3 Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
## Australia
#3/3 Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
仅 sed
和 grep
:
prakhar@inS4n3 ~ $ COUNT=$(grep -c "Server" /etc/pacman.d/mirrorlist.pacnew); cat /etc/pacman.d/mirrorlist.pacnew | sed -r 's/^#([^#]+)//;tx;d;:x'| sed = | sed 'N;s/\n/ /' | sed -r 's/([0-9]+?)\sServer\s=\s(.*)/# \/ '$COUNT' Trying \nServer = /'
...
#241 / 247 Trying http://mirrors.rutgers.edu/archlinux/$repo/os/$arch
Server = http://mirrors.rutgers.edu/archlinux/$repo/os/$arch
#242 / 247 Trying http://mirror.umd.edu/archlinux/$repo/os/$arch
Server = http://mirror.umd.edu/archlinux/$repo/os/$arch
#243 / 247 Trying http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch
Server = http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch
#244 / 247 Trying http://mirrors.xmission.com/archlinux/$repo/os/$arch
...
待办事项:
- 我很确定这不是最优的。
- 难以阅读
- 删除通用评论 (#Worldwide)
编辑:处理一般评论:
user@host $ RANDOM_CHARACTER='@'
user@host $ sed ':b;N; $!bb; s|\n|'"$RANDOM_CHARACTER"'|g;s/#Server/#\nServer/g' /etc/pacman.d/mirrorlist.pacnew | \
sed '2,$=' | \
sed -r '/^[0-9]*$/{s|(.*)|echo "$((-1))/'$COUNT' "|e; N; s|\n([^'"$RANDOM_CHARACTER"']*)|'"$RANDOM_CHARACTER"'|}' | \
sed ':b;N; $!bb;s|\n||g;s|'"$RANDOM_CHARACTER"'|\n|g'
根据文件内容选择随机字符 - 文件中不存在且未用作 sed 命令分隔符的任何字符。
我有一个文件 (mirrorlist.pacnew
) 包含这样的镜像:
prakhar@inS4n3 ~ $ cat /etc/pacman.d/mirrorlist.pacnew
...
## Worldwide
#Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
#Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
## Australia
#Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
...
我应该选择镜像并取消注释。然而,一个工具 rankmirrors
为我确定了最好的镜像,所以我使用 sed
来 取消对所有镜像的注释 .
prakhar@inS4n3 ~ $ cat /etc/pacman.d/mirrorlist.pacnew | sed -r 's/^#([^#]+)/#\n/'
...
## Worldwide
#Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
#Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
## Australia
#Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
...
我保留注释行,因为 rankmirrors 打印它们并且我可以跟踪进度(它不打印它正在处理的未注释行)。
但是,我希望 sed
或 awk
在每行中打印 服务器计数和总计数 。
具体来说:
- 取消注释行,如我在上面给出的示例。
- 从原始文件打印当前#Server索引的索引(不是实际行号,因为文件包含县名,通用注释)。
最终输出看起来像这样:
#22/247 Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
Here 是完整文件的副本。
编辑:
我自己取得了一些进步,我将我的工作添加为
将同一个文件传递给 awk 两次。第一关,算数。二传,替补。
awk 'NR==FNR {
if( /^#Server *=/)count++;
next;
}
/#Server *=/{
sub(/^#*/,"");
print "#" ++i "/" count " " [=10=];
}
1' serverlist serverlist
给出:
## Worldwide
#1/3 Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
Server = https://dgix.ru/mirrors/archlinux/$repo/os/$arch
#2/3 Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch
## Australia
#3/3 Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
Server = http://mirror.aarnet.edu.au/pub/archlinux/$repo/os/$arch
sed
和 grep
:
prakhar@inS4n3 ~ $ COUNT=$(grep -c "Server" /etc/pacman.d/mirrorlist.pacnew); cat /etc/pacman.d/mirrorlist.pacnew | sed -r 's/^#([^#]+)//;tx;d;:x'| sed = | sed 'N;s/\n/ /' | sed -r 's/([0-9]+?)\sServer\s=\s(.*)/# \/ '$COUNT' Trying \nServer = /'
...
#241 / 247 Trying http://mirrors.rutgers.edu/archlinux/$repo/os/$arch
Server = http://mirrors.rutgers.edu/archlinux/$repo/os/$arch
#242 / 247 Trying http://mirror.umd.edu/archlinux/$repo/os/$arch
Server = http://mirror.umd.edu/archlinux/$repo/os/$arch
#243 / 247 Trying http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch
Server = http://mirror.vtti.vt.edu/archlinux/$repo/os/$arch
#244 / 247 Trying http://mirrors.xmission.com/archlinux/$repo/os/$arch
...
待办事项:
- 我很确定这不是最优的。
- 难以阅读
- 删除通用评论 (#Worldwide)
编辑:处理一般评论:
user@host $ RANDOM_CHARACTER='@'
user@host $ sed ':b;N; $!bb; s|\n|'"$RANDOM_CHARACTER"'|g;s/#Server/#\nServer/g' /etc/pacman.d/mirrorlist.pacnew | \
sed '2,$=' | \
sed -r '/^[0-9]*$/{s|(.*)|echo "$((-1))/'$COUNT' "|e; N; s|\n([^'"$RANDOM_CHARACTER"']*)|'"$RANDOM_CHARACTER"'|}' | \
sed ':b;N; $!bb;s|\n||g;s|'"$RANDOM_CHARACTER"'|\n|g'
根据文件内容选择随机字符 - 文件中不存在且未用作 sed 命令分隔符的任何字符。