Answers:
使用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
这是一个品味问题。
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
$
?例如s/[a-zA-Z]*$/replace/
\+
代替,*
因为后者允许在字符串末尾使用零个字母;2)您可以使用字符类[[:alpha:]]
。所以:sed 's/[[:alpha:]]\+$/replace/' file
-r
选项的GNU sed 使用此正则表达式语法。
从您发布的(断)代码段中,您似乎还希望替换换行符。在这种情况下,正则表达式锚本身无法为您提供帮助。以下是解决方案:
sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file
细分:
/[a-zA-Z]\+$/{}
意味着将curlies内部的所有内容应用于与正则表达式匹配的行。 N
表示“将下一行追加到活动缓冲区”(sed
称为“模式空间”)s///
语句是您所需的替代。现在可以使用,因为模式空间包含两行连续的行,因此换行是其中的一部分。