在以下文件中:
Lorem ipsum dolor 坐在 amet,consectetuer adipiscing elit。 Ut eu metus id lectus 前庭 ultrices。梅塞纳斯·隆克斯。
我想删除之前consectetuer
和之后的所有内容elit
。
我想要的输出:
consectetuer adipiscing elit.
我怎样才能做到这一点?
答案1
我会使用 sed
sed 's/^.*\(consectetuer.*elit\).*$/\1/' file
解码 sed s/find/replace/ 语法:
s/^.*
-- 替换从行首 (^
) 开始,后跟任何内容 (.*
) 直到...\(
- 启动一个命名块consectetuer.*elit\.
- 匹配第一个单词,所有 (.*
) 到最后一个单词(在本例中,包括尾随(转义)点)要匹配\)
- 结束命名块- 将其他所有内容 (
.*
) 与行尾 ($
)匹配 /
- 结束替代查找部分\1
\(
- 替换为上面和\)
上面之间的名称块/
- 结束替换
答案2
如果每行包含开始和结束模式,那么最简单的方法是使用grep
.代替删除每行的开头和结尾,您可以简单地输出两种模式之间的内容。-o
GNU 中的选项仅grep
输出匹配项:
grep -o 'consectetuer.*elit' file
注意:如上所述,只有当文件中的每一行都可以这样解析时,这才有效。话又说回来,这占所有典型用例的 80%。
答案3
我不确定为什么这个问题标题已被编辑“从文件“ 到 ”从一条线”虽然OP并不排除跨多行的可能性,即使示例似乎只有一行。无论如何,在这里提供多行解决方案可能会有所帮助。
这适用于交叉线(from1
如果且to2
存在于文件中,则此答案有效。):
from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
例子:
[xiaobai@xiaobai tmp]$ cat file
1
abc consectetuer lsl
home
def elit dd
2 consectetuer ABC elit
[xiaobai@xiaobai tmp]$ from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
consectetuer lsl
home
def elit
[xiaobai@xiaobai tmp]$
参考:外壳参数扩展
答案4
一种 Perl 方式。这本质上是相同的迈克V的sed
回答:
perl -pe 's/.*(consectetuer.*elit).*./$1/' file
意思-p
是“在应用给定的脚本后打印每一行-e
”。是s/foo/bar/
替换运算符;它将替换foo
为bar
.括号捕获了一个模式,让我们在替换中使用它。第一个捕获的模式是$1
,第二个$2
,依此类推。
因此,该命令将匹配consectetuer
( .*consectetuer
) 之前的所有内容,然后是elit
( .*elit
) 之前的所有内容,然后是行尾 ( .*
) 之前的所有内容,并将其替换为捕获的模式。