匹配第 n 次出现的模式并删除,直到找到另一个多括号表达式模式
Matching pattern's nth occurence and delete until another multiple-brackets-expression pattern is found
我想编写一个 shell 脚本来匹配“%”字符并删除所有内容,直到找到特定字符。具体的字符范围在[A-G]
、[a-g]
、[m-n]
、[p-s]
括号内。
例如,我想将 %0.h2d
更改为 %d
。
到目前为止,我已经查看了很多解决方案,但没有找到我要找的东西,尤其是关于多个括号的问题。我对下面代码的最初计划是先隔离字符串,然后再进行删除:
awk '{for(i=1;i<=NF;i++) {if ($i == "%") beginning=i; if($i == [ A-G ] || $i == [ a-g ] || $i ==[ m-n ] || $i == [ p-s ]) ending=i }; for (j=beginning;j<=endin g;j++) printf $j" ";printf "\n" }' .annex/file.c
我的代码语法不正确,我得到的是一堆警告:
awk: syntax error at source line 1
context is
{for(i=1;i<=NF;i++) {if ($i == "%") beginning=i; if($i == >>> [ <<<
awk: illegal statement at source line 1
awk: illegal statement at source line 1`
当 %
被看到 n
次时,我如何修改此代码或使用另一个代码删除 %
和 [A-G] || [a-g] || [m-n] || [p-s]
之间的内容?
尝试:
awk '{gsub(/%[^A-Ga-gm-np-s]+/, "%")} 1' .annex/file.c
例子
考虑这个输入文件:
$ cat file.c
fprintf(stdout,"%-20s %0.h2d",a,b)
fprintf(stderr,"%.3f",c)
让我们运行我们的命令:
$ awk '{gsub(/%[^A-Ga-gm-np-s]+/, "%")} 1' file.c
fprintf(stdout,"%s %d",a,b)
fprintf(stderr,"%f",c)
工作原理
gsub(/%[^A-Ga-gm-np-s]+/, "%")
查找匹配 %
后跟不在 A-G
、a-g
、m-n
范围内的字符的任何字符串或 p-s
并将其替换为 %
.
仅替换第 n 次出现
如果只想替换第 n 次出现,请尝试:
sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n"
例如,要替换第二次出现的情况,请使用:
$ n=2; sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n" file.c
fprintf(stdout,"%-20s %d",a,b)
fprintf(stderr,"%.3f",c)
替换第三个:
$ n=3; sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n" file.c
fprintf(stdout,"%-20s %0.h2d",a,b)
fprintf(stderr,"%f",c)
您可以使用任何您喜欢的 n
值。
工作原理
-E
告诉 sed 使用扩展正则表达式(awk 默认的那种)而不是基本正则表达式。
H;1h;$!d;x;
告诉 sed 将文件读入模式 space。
这一系列命令读入整个文件。将此视为成语可能是最简单的。如果你真的想知道血淋淋的细节:
H
- 追加当前行以保留 space
1h
- 如果这是第一行,覆盖保留 space
有了它
$!d
- 如果这不是最后一行,删除模式 space
并跳转到下一行。
x
- 交换保留和模式 space 以将整个文件放入
模式 space
's/%[^A-Ga-gm-np-s]+/%/'"$n"
告诉 sed 替换第 n 次出现的模式。
我想编写一个 shell 脚本来匹配“%”字符并删除所有内容,直到找到特定字符。具体的字符范围在[A-G]
、[a-g]
、[m-n]
、[p-s]
括号内。
例如,我想将 %0.h2d
更改为 %d
。
到目前为止,我已经查看了很多解决方案,但没有找到我要找的东西,尤其是关于多个括号的问题。我对下面代码的最初计划是先隔离字符串,然后再进行删除:
awk '{for(i=1;i<=NF;i++) {if ($i == "%") beginning=i; if($i == [ A-G ] || $i == [ a-g ] || $i ==[ m-n ] || $i == [ p-s ]) ending=i }; for (j=beginning;j<=endin g;j++) printf $j" ";printf "\n" }' .annex/file.c
我的代码语法不正确,我得到的是一堆警告:
awk: syntax error at source line 1
context is
{for(i=1;i<=NF;i++) {if ($i == "%") beginning=i; if($i == >>> [ <<<
awk: illegal statement at source line 1
awk: illegal statement at source line 1`
当 %
被看到 n
次时,我如何修改此代码或使用另一个代码删除 %
和 [A-G] || [a-g] || [m-n] || [p-s]
之间的内容?
尝试:
awk '{gsub(/%[^A-Ga-gm-np-s]+/, "%")} 1' .annex/file.c
例子
考虑这个输入文件:
$ cat file.c
fprintf(stdout,"%-20s %0.h2d",a,b)
fprintf(stderr,"%.3f",c)
让我们运行我们的命令:
$ awk '{gsub(/%[^A-Ga-gm-np-s]+/, "%")} 1' file.c
fprintf(stdout,"%s %d",a,b)
fprintf(stderr,"%f",c)
工作原理
gsub(/%[^A-Ga-gm-np-s]+/, "%")
查找匹配 %
后跟不在 A-G
、a-g
、m-n
范围内的字符的任何字符串或 p-s
并将其替换为 %
.
仅替换第 n 次出现
如果只想替换第 n 次出现,请尝试:
sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n"
例如,要替换第二次出现的情况,请使用:
$ n=2; sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n" file.c
fprintf(stdout,"%-20s %d",a,b)
fprintf(stderr,"%.3f",c)
替换第三个:
$ n=3; sed -E 'H;1h;$!d;x; s/%[^A-Ga-gm-np-s]+/%/'"$n" file.c
fprintf(stdout,"%-20s %0.h2d",a,b)
fprintf(stderr,"%f",c)
您可以使用任何您喜欢的 n
值。
工作原理
-E
告诉 sed 使用扩展正则表达式(awk 默认的那种)而不是基本正则表达式。H;1h;$!d;x;
告诉 sed 将文件读入模式 space。这一系列命令读入整个文件。将此视为成语可能是最简单的。如果你真的想知道血淋淋的细节:
H
- 追加当前行以保留 space1h
- 如果这是第一行,覆盖保留 space 有了它$!d
- 如果这不是最后一行,删除模式 space 并跳转到下一行。x
- 交换保留和模式 space 以将整个文件放入 模式 space
's/%[^A-Ga-gm-np-s]+/%/'"$n"
告诉 sed 替换第 n 次出现的模式。