在 Linux 中计算两个模式之间的模式总数(如果可能使用 sed)
Count total number of pattern between two pattern (using sed if possible) in Linux
我必须计算两个模式之间的所有“=”,即“{”和“}”
示例:
{
100="1";
101="2";
102="3";
};
{
104="1,2,3";
};
{
105="1,2,3";
};
预期输出:
3
1
1
Perl 来拯救:
perl -lne '$c = 0; $c += ("" =~ tr/=//) while /\{(.*?)\}/g; print $c' < input
-n
逐行读取输入
-l
为每个 print
添加一个换行符
/\{(.*?)\}/g
是正则表达式。 ?
使星号节俭,即匹配最短的字符串。
(...)
括号创建一个捕获组,引用为</code>。</li>
<li><code>tr
一般用于音译(即用一个字符替换另一个字符),但这里只是统计等号的个数。
+=
将数字添加到 $c
.
一个非常神秘的 perl 答案:
perl -nE 's/\{(.*?)\}/ say ( =~ tr{=}{=}) /ge'
tr
函数returns音译的字符数。
根据新要求,我们可以做一些小改动:
perl -0777 -nE 's/\{(.*?)\}/ say ( =~ tr{=}{=}) /ges'
-0777
将整个 file/stream 读入单个字符串
s///
函数的 s
标志允许 .
像普通字符一样处理换行符。
awk 也来了
grep -o '{[^}]\+}'|awk -v FS='=' '{print NF-1}'
例子
echo '{100="1";101="2";102="3";};
{104="1,2,3";};
{105="1,2,3";};'|grep -o '{[^}]\+}'|awk -v FS='=' '{print NF-1}'
输出
3
1
1
首先是一些测试输入(大括号外和内容内有=的一行,一个没有括号,一个只有2个括号)
echo '== {100="1";101="2";102="3=3=3=3";} =;
a=b
{c=d}
{}'
处理不带括号的行(放置一个虚拟字符,这样您就不会以空字符串结尾)
sed -e 's/^[^{]*$/x/'
处理不带等号的行(放置一个虚拟字符,这样您就不会以空字符串结尾)
sed -e 's/{[^=]*}/x/'
删除括号外的内容
sed -e 's/.*{\(.*\)}//'
删除双引号内的内容(不计算那里的字段)
sed -e 's/"[^"]*"//g'
使用@repzero 方法计算等号
awk -F "=" '{print NF-1}'
合并东西
echo -e '{100="1";101="2";102="3";};\na=b\n{c=d}\n{}' |
sed -e 's/^[^{]*$/x/' -e 's/{[^=]*}/x/' -e 's/.*{\(.*\)}//' -e 's/"[^"]*"//g' |
awk -F "=" '{print NF-1}'
丑陋的临时字段 x 和替换 {}
可以在 awk 中解决:
echo -e '= {100="1";101="2=2=2=2";102="3";};\na=b\n{c=d}\n{}' |
sed -e 's/^[^{]*$//' -e 's/.*{\(.*\)}//' -e 's/"[^"]*"//g' |
awk -F "=" '{if (NF>0) c=NF-1; else c=0; print c}'
或更短
echo -e '= {100="1";101="2=2=2=2";102="3";};\na=b\n{c=d}\n{}' |
sed -e 's/^[^{]*$//' -e 's/.*{\(.*\)}//' -e 's/"[^"]*"//g' |
awk -F "=" '{print (NF>0) ? NF-1 : 0; }'
不难 sed
完成...在.
将此答案限制在标记的环境中,即:
linux shell unix sed wc
实际上不需要使用 wc(或 awk
、perl
或任何其他应用程序)。
虽然使用了echo
,但文件源很容易排除它的使用。
至于bash
,就是shell.
最后记录了实际使用的环境
NB. Exploitation of GNU specific extensions has been used for brevity
but appropriately annotated to make a more generic implementation.
Also brace bracketed { text } will not include braces in the text.
It is implicit that such braces should be present as {} pairs but
the text src. dangling brace does not directly violate this tenet.
This is a foray into the world of `sed`'ng to gain some fluency in it's use for other purposes.
The ideas expounded upon here are used to cross pollinate another SO problem solution in order
to aquire more familiarity with vetting vagaries of vernacular version variances. Consequently
this pedantic exercice hopefully helps with the pedagogy of others beyond personal edification.
To test easily, at least in the environment noted below, judiciously highlight the appropriate
code section, carefully excluding a dangling pipe |, and then, to a CLI command line interface
drag & drop, copy & paste or use middle click to enter the code.
The other SO problem. linux - Is it possible to do simple arithmetic in sed addresses?
# _______________________________ always needed ________________________________
echo -e '\n
\n = = = {\n } = = = each = is outside the braces
\na\nb\n { } so therefore are not counted
\nc\n { = = = = = = = } while the ones here do count
{\n100="1";\n101="2";\n102="3";\n};
\n {\n104="1,2,3";\n};
a\nb\nc\n {\n105="1,2,3";\n};
{ dangling brace ignored junk = = = \n' |
# _____________ prepatory conditioning needed for final solutions _____________
sed ' s/{/\n{\n/g;
s/}/\n}\n/g; ' | # guarantee but one brace to a line
sed -n '/{/ h; # so sed addressing can "work" here
/{/,/}/ H; # use hHold buffer for only { ... }
/}/ { x; s/[^=]*//g; p } ' | # then make each {} set a line of =
# ____ stop code hi-lite selection in ^--^ here include quote not pipe ____
# ____ outputs the following exclusive of the shell " # " comment quotes _____
#
#
# =======
# ===
# =
# =
# _________________________________________________________________________
# ____________________________ "simple" GNU solution ____________________________
sed -e '/^$/ { s//0/;b }; # handle null data as 0 case: next!
s/=/\n/g; # to easily count an = make it a nl
s/\n$//g; # echo adds an extra nl - delete it
s/.*/echo "&" | sed -n $=/; # sed = command w/ $ counts last nl
e ' # who knew only GNU say you ah phoo
# 0
# 0
# 7
# 3
# 1
# 1
# _________________________________________________________________________
# ________________________ generic incomplete "solution" ________________________
sed -e '/^$/ { s//echo 0/;b }; # handle null data as 0 case: next!
s/=$//g; # echo adds an extra nl - delete it
s/=/\\n/g; # to easily count an = make it a nl
s/.*/echo -e & | sed -n $=/; '
# _______________________________________________________________________________
用于该算法的范例是由下面的序言研究发起的。
这个想法是将 =
符号组隔离在 { }
大括号之间进行计数。
找到这些,每组都放在单独的一行上,并删除所有其他装饰字符。
需要注意的是 sed
可以很容易地“计数”,实际上枚举 nl 或 \n 行结束于 =
.
第一个“解决方案”使用这些 sed
命令:
p
打印
b
牧场w/o标签开始新的循环
h
/H
旧用于填充此 sed
缓冲区
- e
x
改变保持和模式缓冲区
=
枚举当前sed
输入行
s
将s/.../.../;
替换为g
局部标志s/.../.../g;
尤其是 GNU 特定的
e
valuate(e
xecute记不住实际助记词但无关紧要的同义词)
通用代码中避免了 GNU 特定的 e
xecute 命令。它不打印答案但是
而是生成将打印答案的代码。 运行 观察一下吧。为了完全自动化,许多
可以使用一些机制,其中最重要的是 sed
w
rite 命令将这些行放在
shell 要执行的文件,甚至将输出嵌入 bash
评估括号 $( )
等
另请注意,各种 sed
示例脚本可以“计数”,并且这些脚本也可以有效地使用。
有兴趣的 reader 可以考虑这些其他的追求。
导言:
计算大括号之间行数的概念
sed -n '/{/=;/}/=;'
至
sed -n '/}/=;/{/=;' |
sed -n 'h;n;G;s/\n/ - /;
2s/^/ Between sets of {} \n the nl # count is\n /;
2!s/^/ /;
p'
测试“完成”:
linuxuser@ubuntu:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.2 LTS
Release: 18.04
Codename: bionic
linuxuser@ubuntu:~$ sed --version -----> sed (GNU sed) 4.4
还有一个 awk
唯一的替代方案:
echo '{
> 100="1";
> 101="2";
> 102="3";
> };
> {
> 104="1,2,3";
> };
> {
> 105="1,2,3";
> };' | awk 'BEGIN{RS="\n};";FS="\n"}{c=gsub(/=/,""); if(NF>2){print c}}'
3
1
1
我必须计算两个模式之间的所有“=”,即“{”和“}” 示例:
{
100="1";
101="2";
102="3";
};
{
104="1,2,3";
};
{
105="1,2,3";
};
预期输出:
3
1
1
Perl 来拯救:
perl -lne '$c = 0; $c += ("" =~ tr/=//) while /\{(.*?)\}/g; print $c' < input
-n
逐行读取输入-l
为每个print
添加一个换行符
/\{(.*?)\}/g
是正则表达式。?
使星号节俭,即匹配最短的字符串。(...)
括号创建一个捕获组,引用为</code>。</li> <li><code>tr
一般用于音译(即用一个字符替换另一个字符),但这里只是统计等号的个数。+=
将数字添加到$c
.
一个非常神秘的 perl 答案:
perl -nE 's/\{(.*?)\}/ say ( =~ tr{=}{=}) /ge'
tr
函数returns音译的字符数。
根据新要求,我们可以做一些小改动:
perl -0777 -nE 's/\{(.*?)\}/ say ( =~ tr{=}{=}) /ges'
-0777
将整个 file/stream 读入单个字符串s///
函数的s
标志允许.
像普通字符一样处理换行符。
awk 也来了
grep -o '{[^}]\+}'|awk -v FS='=' '{print NF-1}'
例子
echo '{100="1";101="2";102="3";};
{104="1,2,3";};
{105="1,2,3";};'|grep -o '{[^}]\+}'|awk -v FS='=' '{print NF-1}'
输出
3
1
1
首先是一些测试输入(大括号外和内容内有=的一行,一个没有括号,一个只有2个括号)
echo '== {100="1";101="2";102="3=3=3=3";} =;
a=b
{c=d}
{}'
处理不带括号的行(放置一个虚拟字符,这样您就不会以空字符串结尾)
sed -e 's/^[^{]*$/x/'
处理不带等号的行(放置一个虚拟字符,这样您就不会以空字符串结尾)
sed -e 's/{[^=]*}/x/'
删除括号外的内容
sed -e 's/.*{\(.*\)}//'
删除双引号内的内容(不计算那里的字段)
sed -e 's/"[^"]*"//g'
使用@repzero 方法计算等号
awk -F "=" '{print NF-1}'
合并东西
echo -e '{100="1";101="2";102="3";};\na=b\n{c=d}\n{}' |
sed -e 's/^[^{]*$/x/' -e 's/{[^=]*}/x/' -e 's/.*{\(.*\)}//' -e 's/"[^"]*"//g' |
awk -F "=" '{print NF-1}'
丑陋的临时字段 x 和替换 {}
可以在 awk 中解决:
echo -e '= {100="1";101="2=2=2=2";102="3";};\na=b\n{c=d}\n{}' |
sed -e 's/^[^{]*$//' -e 's/.*{\(.*\)}//' -e 's/"[^"]*"//g' |
awk -F "=" '{if (NF>0) c=NF-1; else c=0; print c}'
或更短
echo -e '= {100="1";101="2=2=2=2";102="3";};\na=b\n{c=d}\n{}' |
sed -e 's/^[^{]*$//' -e 's/.*{\(.*\)}//' -e 's/"[^"]*"//g' |
awk -F "=" '{print (NF>0) ? NF-1 : 0; }'
不难 sed
完成...在.
将此答案限制在标记的环境中,即:
linux shell unix sed wc
实际上不需要使用 wc(或 awk
、perl
或任何其他应用程序)。
虽然使用了echo
,但文件源很容易排除它的使用。
至于bash
,就是shell.
最后记录了实际使用的环境
NB. Exploitation of GNU specific extensions has been used for brevity but appropriately annotated to make a more generic implementation. Also brace bracketed { text } will not include braces in the text. It is implicit that such braces should be present as {} pairs but the text src. dangling brace does not directly violate this tenet.This is a foray into the world of `sed`'ng to gain some fluency in it's use for other purposes. The ideas expounded upon here are used to cross pollinate another SO problem solution in order to aquire more familiarity with vetting vagaries of vernacular version variances. Consequently this pedantic exercice hopefully helps with the pedagogy of others beyond personal edification. To test easily, at least in the environment noted below, judiciously highlight the appropriate code section, carefully excluding a dangling pipe |, and then, to a CLI command line interface drag & drop, copy & paste or use middle click to enter the code.
The other SO problem. linux - Is it possible to do simple arithmetic in sed addresses?
# _______________________________ always needed ________________________________
echo -e '\n
\n = = = {\n } = = = each = is outside the braces
\na\nb\n { } so therefore are not counted
\nc\n { = = = = = = = } while the ones here do count
{\n100="1";\n101="2";\n102="3";\n};
\n {\n104="1,2,3";\n};
a\nb\nc\n {\n105="1,2,3";\n};
{ dangling brace ignored junk = = = \n' |
# _____________ prepatory conditioning needed for final solutions _____________
sed ' s/{/\n{\n/g;
s/}/\n}\n/g; ' | # guarantee but one brace to a line
sed -n '/{/ h; # so sed addressing can "work" here
/{/,/}/ H; # use hHold buffer for only { ... }
/}/ { x; s/[^=]*//g; p } ' | # then make each {} set a line of =
# ____ stop code hi-lite selection in ^--^ here include quote not pipe ____
# ____ outputs the following exclusive of the shell " # " comment quotes _____
#
#
# =======
# ===
# =
# =
# _________________________________________________________________________
# ____________________________ "simple" GNU solution ____________________________
sed -e '/^$/ { s//0/;b }; # handle null data as 0 case: next!
s/=/\n/g; # to easily count an = make it a nl
s/\n$//g; # echo adds an extra nl - delete it
s/.*/echo "&" | sed -n $=/; # sed = command w/ $ counts last nl
e ' # who knew only GNU say you ah phoo
# 0
# 0
# 7
# 3
# 1
# 1
# _________________________________________________________________________
# ________________________ generic incomplete "solution" ________________________
sed -e '/^$/ { s//echo 0/;b }; # handle null data as 0 case: next!
s/=$//g; # echo adds an extra nl - delete it
s/=/\\n/g; # to easily count an = make it a nl
s/.*/echo -e & | sed -n $=/; '
# _______________________________________________________________________________
用于该算法的范例是由下面的序言研究发起的。
这个想法是将 =
符号组隔离在 { }
大括号之间进行计数。
找到这些,每组都放在单独的一行上,并删除所有其他装饰字符。
需要注意的是 sed
可以很容易地“计数”,实际上枚举 nl 或 \n 行结束于 =
.
第一个“解决方案”使用这些 sed
命令:
p
打印b
牧场w/o标签开始新的循环h
/H
旧用于填充此sed
缓冲区- e
x
改变保持和模式缓冲区 =
枚举当前sed
输入行s
将s/.../.../;
替换为g
局部标志s/.../.../g;
尤其是 GNU 特定的
e
valuate(e
xecute记不住实际助记词但无关紧要的同义词)
通用代码中避免了 GNU 特定的 e
xecute 命令。它不打印答案但是
而是生成将打印答案的代码。 运行 观察一下吧。为了完全自动化,许多
可以使用一些机制,其中最重要的是 sed
w
rite 命令将这些行放在
shell 要执行的文件,甚至将输出嵌入 bash
评估括号 $( )
等
另请注意,各种 sed
示例脚本可以“计数”,并且这些脚本也可以有效地使用。
有兴趣的 reader 可以考虑这些其他的追求。
导言: 计算大括号之间行数的概念
sed -n '/{/=;/}/=;'
至
sed -n '/}/=;/{/=;' |
sed -n 'h;n;G;s/\n/ - /;
2s/^/ Between sets of {} \n the nl # count is\n /;
2!s/^/ /;
p'
测试“完成”:
linuxuser@ubuntu:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.2 LTS
Release: 18.04
Codename: bionic
linuxuser@ubuntu:~$ sed --version -----> sed (GNU sed) 4.4
还有一个 awk
唯一的替代方案:
echo '{
> 100="1";
> 101="2";
> 102="3";
> };
> {
> 104="1,2,3";
> };
> {
> 105="1,2,3";
> };' | awk 'BEGIN{RS="\n};";FS="\n"}{c=gsub(/=/,""); if(NF>2){print c}}'
3
1
1