我正在寻找一种仅在最后一个字符是换行符时才执行替换的方法,使用sed
.
例如:
lettersAtEndOfLine
被替换,但这不是:
lettersWithCharacterAfter&
由于sed
不能很好地处理换行符,因此它并不像
$ sed -E "s/[a-zA-Z]*\n/replace/" file.txt
如何才能做到这一点?
答案1
有了标准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
这是一个品味问题。
答案2
sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt
或者,漫长而复杂的不必要的方式:
我发现,这可以完成,仍然使用 sed,在 tr 的帮助下。您可以指定另一个字符来表示行尾。必须使用另一个临时字符,在本例中为“`”。我们用“~”来表示行尾:
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
从您发布的(损坏的)代码片段来看,您似乎也想替换换行符。在这种情况下,正则表达式锚定本身无法帮助您。下面是一个解决方案:
sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file
细分:
答案4
要找到行尾,只需使用$符号:
没有行尾锚点:
sed -n '/pattern/p' file
使用行尾锚点:
sed -n '/pattern$/p' file