如何在 2 个特殊字符之间 sed 或 grep 并修改输出



我想在 ! 和 ?例如

!X hello my name is X?

X 是 0-9
之间的数字并将其输出到

Xhello my name isX

我当然想在文本文件中获取所有这些模式并删除其他任何内容

例:

blabla
foo bar !3 whats up 3?
!4 hello im new
to this forum 4?
foo bar now

结果:

3whats up3
4hello im new to this forum4

也许有人可以帮助我,我只想使用 sh 和这个命令

假设我们有一个包含内容的输入文件(故意复杂以涵盖扩展情况(:

blabla !1
foo bar !3 whats up 3?
sdfsdf
sdf !33333?
!4 hello im new
to this forum 4?
foo bar now
!344 dd!4 sdf?fff 44?

两种方法:

-- awk 方法:

awk -v RS='!' 'match($0,/^([0-9]) ([^!?]*) ([0-9])?/,a){ gsub(/n/,"",a[2]); print a[1]a[2]a[3] }' file
  • -v RS='!' - 将!视为记录分隔符

  • match($0,/^([0-9]) ([^!?]*) ([0-9])?/,a) - 匹配所需的序列并将捕获的组(..)值放入数组a


-- 粘贴 + grep + sed 管道:

paste -d' ' -s file | grep -o '![0-9] [^!?]* [0-9]?' | sed -En 's/!([0-9]+) (.*) ([0-9]+)?/123/p'
  • paste -d' ' -s file - 使用空格作为分隔符合并文件

  • grep -o '![0-9] [^!?]* [0-9]?' - 搜索并仅输出与模式匹配的所需序列

  • sed -En 's/!([0-9]+) (.*) ([0-9]+)?/123/p' - 在捕获的组下执行替换


输出(对于两种方法(:

3whats up3
4hello im new to this forum4
单个

awk命令,虽然不微不足道,但很有效:

awk '
  {
    from = match($0, "![0-9] ")
    if (from) {
      $0 = substr($0, from+1, RLENGTH-2) substr($0, from + RLENGTH)
    }
    to = match($0, " [0-9]\?")
    if (to) {
      $0 = substr($0, 1, to-1) substr($0, to+1, length($0)-to-1)
    }
    if (from && to)  print
    else if (from)   printf "%s ", $0
    else if (to)     print
  }
' file

注意:假设没有!<digit> ... <digit>?序列跨越超过 2 行(使解决方案适应这种情况并不难(。

使用 GNU awk:

$ cat file2
blabla
foo bar !3 whats up 3?
!4 hello im new
to this forum 4?
foo bar 2345 now
$ awk -v RS="[!?]" '{gsub("n"," ")}$0 ~ /^[0-9].*[0-9]$/{sub(" ","");print gensub(/ ([0-9]$)/,"\1","g")}' file2
3whats up3
4hello im new to this forum4

这可能对你有用(GNU sed & tr(:

tr 'n!?' ' nn' < file |
sed -nr '/^([0-9]).*1$/s/^([0-9])s*|s*([0-9])$/12/gp'

将换行符转换为空格,将!?转换为换行符。然后检查每行是否以相同的数字开头和结尾,如果是,请删除上述数字之前或之前的任何空格并打印结果。

可以在两个 sed 调用中完成,如下所示:

sed -z 'y/n!?/ nn/' file |
sed -nr '/^([0-9]).*1$/s/^([0-9])s*|s*([0-9])$/12/gp'

或:

sed 'H;$!d;x;y/n!?/ nn/' file | 
sed -nr '/^([0-9]).*1$/s/^([0-9])s*|s*([0-9])$/12/gp'

或作为一个:

sed -nr '/n/ba;H;$!d;x;y/n!?/ nn/;s/^([0-9])s*|s*([0-9])$/12/Mg;:a;/^([0-9])[^n]*1n/P;D' file

最新更新