我想在 ! 和 ?例如
!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