如何使用sed检测行尾


15

我正在寻找一种仅在最后一个字符为换行符时执行替换的方法sed

例如:

lettersAtEndOfLine

被替换,但这不是:

lettersWithCharacterAfter&

由于sed不适用于换行符,因此它不如简单

$ sed -E "s/[a-zA-Z]*\n/replace/" file.txt

如何做到这一点?

Answers:


21

使用standard sed,您将永远不会在从文件中读取的文本中看到换行符。这是因为sed逐行读取,因此在sed模式空间中当前行文本的末尾没有换行符。换句话说,sed读取以换行符分隔的数据,并且分隔符不是sed脚本所见内容的一部分。

可以使用(或在开头使用)将正则表达式固定在行的末尾。在行的开头/结尾处锚定表达式会强制其完全匹配,而不仅仅是行中的任何地方。$^

如果要用行替换模式[A-Za-z]*末尾与模式匹配的任何内容,请按以下方式锚定模式:

[A-Za-z]*$

...将迫使它在行尾匹配,其他任何地方都不会匹配。

但是,由于[A-Za-z]*$也不匹配任何内容(例如,行末尾出现的空字符串),因此您需要强制匹配某个内容,例如,通过指定

[A-Za-z][A-Za-z]*$

要么

[A-Za-z]\{1,\}$

因此,您的sed命令行将是

$ sed 's/[A-Za-z]\{1,\}$/replace/' file.txt

我没有在-E这里使用该开关,因为它是不需要的。有了它,你可能已经写了

$ sed -E 's/[A-Za-z]+$/replace/' file.txt

这是一个品味问题。


评论不作进一步讨论;此对话已转移至聊天
库萨兰达

3
sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt

或者,长而复杂的不必要方法:

我发现,仍然可以在tr的帮助下使用sed来完成此操作。您可以分配另一个字符来表示行尾。必须使用另一个临时字符,在这种情况下为“`”。让我们用“〜”代表行尾:

tr '\n' '`' <input.txt >output.txt
sed -i "s/`/~`/" output.txt
tr '`' '\n' <output.txt >result.txt

然后要执行实际的搜索和替换,请使用“〜”而不是“ \ n”:

sed -i -E "s/[a-zA-Z]*~/replace/" result.txt

然后清除其他行上的多余字符:

sed -i "s/~//" result.txt

显然,所有这些都可以通过管道传递到一起,从而导致类似:

tr '\n' '`' <input.txt | sed -e "s/`/~`/" | tr '`' '\n' | sed -E -e "s/[a-zA-Z]*~/replace/" | sed "s/~//" > result.txt

3
不知道我能理解...为什么您不只是锚定在行尾$?例如s/[a-zA-Z]*$/replace/
don_crissti

1
2分:1)最好使用\+代替,*因为后者允许在字符串末尾使用零个字母;2)您可以使用字符类[[:alpha:]]。所以:sed 's/[[:alpha:]]\+$/replace/' file
格伦·杰克曼(Glenn jackman)2015年

@glennjackman加号前的反斜杠是什么?那不匹配加法字符吗?
Matthew D. Scholefield,2015年

1
不带-r选项的GNU sed 使用此正则表达式语法
glenn jackman

0

从您发布的(断)代码段中,您似乎还希望替换换行符。在这种情况下,正则表达式锚本身无法为您提供帮助。以下是解决方案:

sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file

细分:

  • /[a-zA-Z]\+$/{} 意味着将curlies内部的所有内容应用于与正则表达式匹配的行。
  • 正则表达式是一种使用锚定的方法,如您自己的答案所示,该正则表达式已修改为将glenn jackman的注释考虑在内。
  • 在curl内,N表示“将下一行追加到活动缓冲区”(sed称为“模式空间”)
  • 最后,该s///语句是您所需的替代。现在可以使用,因为模式空间包含两行连续的行,因此换行是其中的一部分。

0

要找到行尾,只需使用$符号

没有行尾锚:

sed -n '/pattern/p' file 

没有行尾锚:

sed -n '/pattern$/p' file
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.