Sed提供根据特定模式或条件将文本附加到文件中的行的能力。
您可以使用a\
命令输入sed
在模式匹配后添加新行。
让我们深入研究现实世界的示例,以了解如何有效地利用此功能。
在匹配的模式后添加一行
假设您有一个名为的配置文件config.txt
包含以下内容:
server {
listen 80;
server_name example.com;
}
您想在之后添加评论server_name
指令来提醒自己其目的。
sed '/server_name/a\ # This is the domain name for our server' config.txt
Output:
server {
listen 80;
server_name example.com;
# This is the domain name for our server
}
The sed
命令的工作原理如下:
-
/server_name/
:这将在文件中搜索模式“server_name”。
-
a\
:这是追加命令sed
。它说sed
附加以下文本。
-
# This is the domain name for our server
:这是您要附加的文本。请注意,注释前的空格有助于保持文件中的格式。
如果您想直接保存对文件的更改,可以使用-i
标志与sed
:
sed -i '/server_name/a\ # This is the domain name for our server' config.txt
执行该命令后,config.txt
将使用附加文本进行适当修改。
在匹配的模式后追加多行
假设你有一个配置文件,config.txt
,其结构如下:
database {
user db_user;
password db_pass;
}
您希望在后面添加几行注释password
为了清楚起见指令。
sed '/password/a\ # Ensure to change the password regularly.\n # Contact the DB admin for more details.' config.txt
Output:
database {
user db_user;
password db_pass;
# Ensure to change the password regularly.
# Contact the DB admin for more details.
}
The \n
代表一个新行,使我们能够在第一行之后立即添加另一行。
使用基本正则表达式进行模式匹配
基本正则表达式 (BRE) 有助于定义比精确字符串匹配更灵活的搜索模式。
让我们看几个例子,其中基本的正则表达式sed
可能会有帮助。
在以特定模式开头的行之后追加
假设你有一个文件,data.txt
,包含:
apple 5
banana 8
apple 7
cherry 3
您希望在以“apple”开头的行之后添加注释。
sed '/^apple/a\# This is an apple entry' data.txt
Output:
apple 5
# This is an apple entry
banana 8
apple 7
# This is an apple entry
cherry 3
Here, ^apple
是正则表达式。插入符号 (^
) 断言“apple”位于行首。
在以特定模式结尾的行之后追加
与相同的data.txt
,假设您想在以数字“8”结尾的行之后添加注释。
sed '/8$/a\# This line ends with 8' data.txt
Output:
apple 5
banana 8
# This line ends with 8
apple 7
cherry 3
正则表达式8$
查找以数字“8”结尾的行。美元符号 ($
) 确保匹配的字符或字符串位于行尾。
在包含数字的行之后追加
再次,与data.txt
文件中,假设您希望在包含任何数字的行之后发表评论。
sed '/[0-9]/a\# This line has a number' data.txt
Output:
apple 5
# This line has a number
banana 8
# This line has a number
apple 7
# This line has a number
cherry 3
# This line has a number
在这种情况下,模式[0-9]
匹配任何单个数字。
使用扩展正则表达式
扩展正则表达式 (ERE) 通过引入额外的元字符和结构来扩展基本正则表达式的功能,从而允许更高级的模式匹配。
您可以使用sed
通过使用扩展正则表达式-E
flag.
在具有特定单词匹配的行之后追加
假设你有一个文件,words.txt
,包含:
programming
coder
development
programmer
coding
您想要在包含以“ing”或“ment”结尾的单词的行后附加注释。
sed -E '/(ing|ment)$/a\# Relevant profession' words.txt
Output:
programming
# Relevant profession
coder
development
# Relevant profession
programmer
# Relevant profession
coding
# Relevant profession
在这里,图案(ing|ment)$
使用|
匹配行尾的“ing”或“ment”的运算符。
在具有重复模式的行之后追加
与相同的words.txt
,假设您想在具有重复字符的行后面附加注释。
sed -E '/(.)\1/a\# Repeated character detected' words.txt
Output:
programming
# Repeated character detected
coder
development
programmer
# Repeated character detected
coding
# Repeated character detected
正则表达式(.)\1
识别重复的字符。
The (.)
捕获任何字符,同时\1
引用回捕获的字符,确保仅当它连续出现两次时才匹配。
在带有可选匹配的行之后追加
假设您想对包含“code”或“coder”的行进行注释。
sed -E '/cod(er)?/a\# Coding related' words.txt
Output:
programming
coder
# Coding related
development
programmer
coding
# Coding related
在这个模式中,cod(er)?
, the ?
使前面的“er”可选,这意味着它将匹配“code”和“coder”。
根据行号追加
sed
允许您根据特定行号或行号范围附加文本。
当编辑具有已知结构的配置文件或脚本时,此功能特别有用。
让我们深入研究一些例子。
在特定行号之后追加
假设你有一个文件,lines.txt
,看起来像这样:
first line
second line
third line
fourth line
您想在第二行之后添加注释。
Command:
sed '2a\# This is after the second line' lines.txt
Output:
first line
second line
# This is after the second line
third line
fourth line
在此命令中,数字2
之前a\
命令指定追加应发生在第二行之后。
在一系列行号之后追加
使用相同的lines.txt
,假设您想在第 2 行到第 3 行之后添加注释。
sed '2,3a\# This is a comment' lines.txt
Output:
first line
second line
# This is a comment
third line
# This is a comment
fourth line
通过指定2,3
之前a\
命令,您指示追加应该发生在第 2 行和第 3 行(含)之间范围内的每一行之后。
添加到文件末尾(最后一行)
要在文件末尾附加文本,您可以使用以下命令定位最后一行$
.
sed '$a\# This is the end of the file' lines.txt
Output:
first line
second line
third line
fourth line
# This is the end of the file
在不包含模式的行之后追加
假设你有一个文件,tasks.txt
, 其中包含:
Complete the report
Attend the meeting
Send emails
Update the software
假设您想在不包含“Update”一词的行后附加注释。
sed '/Update/!a\Note: This task is regular' tasks.txt
Output:
Complete the report
Note: This task is regular
Attend the meeting
Note: This task is regular
Send emails
Note: This task is regular
Update the software
在这里,!
符号用于否定匹配。所以,模式/Update/!
匹配不包含单词“Update”的行。
在 sed 中处理换行符 (\n)
默认情况下,sed
一次从输入中读取一行并去掉终止换行符。
因此,在一个身体内sed
脚本中,换行符在您引入之前不会出现。
假设您有一个名为sample.txt
包含:
apple
banana
cherry
要在匹配后插入新行:
sed '/banana/a\\ndate\ngrape' sample.txt
Output:
apple
banana
date
grape
cherry
注意双反斜杠的使用\\n
在“日期”之前。
附加带有特殊字符的行
In sed
,某些字符被视为“特殊”,因为它们在命令语法中具有独特的含义。
角色如&
, $
, ^
, *
,以及更多都是正则表达式的基本组成部分或sed
命令构造。
当您想要附加包含这些字符的行时,您需要正确处理它们以避免意外行为。
用 & 追加一行
想象一个名为special.txt
包含以下内容:
start
middle
end
追加一行 $
如果您想添加包含以下内容的行$
“start”后的字符:
sed '/start/a\$100 is the price' special.txt
Output:
start
$100 is the price
middle
end
在这里,$
在追加命令中被简单地视为常规字符。
附加多个特殊字符
对于包含多个特殊字符的行,只需在追加命令中将它们用作常规字符即可:
sed '/end/a\Special chars: & * $ ^ @' special.txt
Output:
start
$100 is the price
middle
end
Special chars: & * $ ^ @
附加 Shell 变量
在脚本和命令行操作中,您经常需要将 shell 变量中的值插值或插入到您的sed
命令。
这可以通过封装来轻松完成sed
命令用双引号括起来,允许 shell 变量扩展。以下是如何实现这一目标:
基本附加变量
考虑一个变量:
user="Alice"
还有一个文件,notes.txt
,其中包含:
Start your day
Reply to emails
要在“回复电子邮件”之后附加带有用户名的自定义消息:
sed "/Reply to emails/a\\
Hello, $user! Have a productive day!" notes.txt
Output:
Start your day
Reply to emails
Hello, Alice! Have a productive day!
处理变量中的特殊字符
如果您的变量如下所示:
path="/home/alice/documents"
要在“开始新的一天”之后附加此路径,您需要为sed
命令:
sed "/Start your day/a\\
$path" notes.txt
Output:
Start your day
/home/alice/documents
Reply to emails
当正斜杠/
通常用作分隔符sed
命令,您可以使用其他分隔符,例如|
, #
, or :
如果您的内容可能与默认内容冲突。
附加 sed 捕获的组
In sed
,捕获组允许您捕获输入模式的部分内容并在以后引用它们。
捕获和附加
让我们考虑一个名为products.txt
包含以下内容:
apple 10
banana 20
cherry 30
您想要在每个产品的行后附加大写的名称。
sed '/\([a-z]*\) [0-9]*/ { h; s/\([a-z]*\) [0-9]*/\U\1/; x; G; }' products.txt
Output:
apple 10
APPLE
banana 20
BANANA
cherry 30
CHERRY
这是发生的事情:
-
/\([a-z]*\) [0-9]*/
:匹配以小写单词开头,后跟空格和数字的行。
-
h
:该命令将模式空间的内容(当前行)复制到保持缓冲区。
-
s/\([a-z]*\) [0-9]*/\U\1/
:这会捕获产品名称并将其转换为大写\U
.
-
x
:该命令交换模式空间和保持缓冲区的内容。
-
G
:这会将保留缓冲区的内容(现在具有大写产品名称)附加到模式空间,实质上是将大写产品名称附加到原始行。
使用多个 -e 选项进行顺序追加
The -e
选项中sed
允许您指定要按顺序应用的多个编辑命令。
当您要对输入执行多个独立的转换或附加操作,并且您希望在一次数据传递中执行它们时,此功能非常有用。
不同行的顺序追加
考虑一个名为agenda.txt
:
Meeting at 10am
Lunch break
Review session
您想要在“上午 10 点会议”和“回顾会议”条目之后附加提醒:
sed -e '/Meeting at 10am/a\Bring presentation slides' -e '/Review session/a\Prepare feedback notes' agenda.txt
Output:
Meeting at 10am
Bring presentation slides
Lunch break
Review session
Prepare feedback notes
将追加与替换相结合
使用相同的agenda.txt
,假设您想在“午休”之后添加提醒并更改会议时间:
sed -e '/Lunch break/a\Visit the new cafe' -e 's/10am/11am/' agenda.txt
Output:
Meeting at 11am
Lunch break
Visit the new cafe
Review session
在这里,-e
选项允许附加和代换单一操作sed
命令。
组织复杂的操作
在处理复杂文件或多次修改时,会破坏您的sed
命令分成多个-e
部分可以使您的命令更具可读性。
例如:
sed -e '/Meeting/a\Ensure the projector is working' \
-e '/Lunch break/a\Confirm reservation' \
-e '/Review session/a\Gather all team feedback' \
agenda.txt
Output:
Meeting at 10am
Ensure the projector is working
Lunch break
Confirm reservation
Review session
Gather all team feedback
附加到大文件的有效方法
处理非常大的文件时,使用诸如sed
可能是资源密集型的。但是,有一些方法可以有效地处理此类操作,而不会耗尽系统内存或 CPU。
使用直接文件重定向
对于简单的任务(例如将内容附加到大文件末尾),直接文件重定向是最有效的:
echo "Your appended content here." >> largefile.txt
该命令会将文本附加到末尾largefile.txt
无需将文件加载到内存中。
拆分、处理和连接(分块)
如果您需要基于某些模式进行追加,请考虑将文件拆分为可管理的块,单独处理每个块,然后连接它们:
Use split
分割大文件:
split -l 1000000 largefile.txt chunk_
该命令分割largefile.txt
分成每个 100 万行的块,命名为chunk_aa
, chunk_ab
, 等等。
处理每个块sed
或其他工具:
for f in chunk_*; do
sed 'your_sed_command' $f > ${f}_processed
done
将处理后的块重新连接在一起:
cat chunk_*_processed > largefile_processed.txt
清理块:
rm chunk_*
避免使用-i
非常大的文件的就地编辑
The -i
选项sed
进行就地编辑,但对于非常大的文件来说效率可能较低,因为它有效地创建了原始文件的副本。
相反,将输出重定向到新文件,然后根据需要重命名。
现实世界的例子
让我们重点关注一些例子sed
a\
使用(追加)命令。
Example:您有一个配置文件,为了清楚起见,您希望在指示新部分开始的注释后附加一个标头。
File: config.conf
# Begin User Configuration
username = guest
password = guest123
Command:
sed '/# Begin User Configuration/a\# Details for the guest user' config.conf
Output:
# Begin User Configuration
# Details for the guest user
username = guest
password = guest123
Example:在 Python 脚本中,您希望在包含单词“FIXME”的行后面附加注释,以提供有关修复问题的提示。
File: script.py
def some_function():
x = y + 2 # FIXME
Command:
sed '/FIXME/a\# A fix is pending for the above line' script.py
Output:
def some_function():
x = y + 2 # FIXME
# A fix is pending for the above line
在配置文件中提供节分隔符
Example:在服务器配置文件中,您需要在每个部分之后附加一个分隔符以提高可读性。
File: server.conf
[database]
user = admin
[logging]
level = INFO
Command:
sed '/\[\w\+\]/a\##########' server.conf
Output:
[database]
##########
user = admin
[logging]
##########
level = INFO
该命令扫描file.txt
,并且每次它找到用方括号括起来的单词(如配置文件中的节标题)时,它会立即在该行后面附加文本“##########”。