出于某种原因,我现在可以在一段时间内处于紧张状态 . 如何使用 sed 命令在匹配特定字符串的第一行之后插入选择行文本 . 我有 ...
sed
CLIENTSCRIPT="foo" CLIENTFILE="bar"
我想在 CLIENTSCRIPT= 行之后插入一行,导致......
CLIENTSCRIPT=
CLIENTSCRIPT="foo" CLIENTSCRIPT2="hello" CLIENTFILE="bar"
尝试使用GNU sed执行此操作:
sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
如果你想在原地替换,请使用
sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file
\a
注意标准 sed 语法(如在POSIX中,因此所有符合 sed 实现的支持(GNU,OS / X,BSD,Solaris ...)):
sed '/CLIENTSCRIPT=/a\ CLIENTSCRIPT2="hello"' file
或者在一条线上:
sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file
( -e xpressions(以及 -f iles的内容)与换行符一起组成sed脚本 sed 解释) .
-e
-f
用于就地编辑的 -i 选项也是GNU扩展,其他一些实现(如FreeBSD)支持 -i '' .
-i
-i ''
或者,为了便于携带,您可以使用 perl 代替:
perl
perl -pi -e '$_ .= qq(CLIENTSCRIPT2="hello"\n) if /CLIENTSCRIPT=/' file
或者您可以使用 ed 或 ex :
ed
ex
printf '%s\n' /CLIENTSCRIPT=/a 'CLIENTSCRIPT2="hello"' . w q | ex -s file
符合POSIX标准的使用 s 命令:
s
sed '/CLIENTSCRIPT="foo"/s/.*/&\ CLIENTSCRIPT2="hello"/' file
Sed命令适用于MacOS(至少OS 10)和Unix一样(即不需要像Gilles(目前接受)那样的gnu sed):
sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file
这适用于bash以及其他可能知道$'\ n'评估报价样式的shell . 一切都可以在一行上,并在旧的/ POSIX sed命令中工作 . 如果可能有多行与CLIENTSCRIPT =“foo”(或您的等效符号)匹配,并且您希望第一次只添加额外的行,则可以按如下方式重做:
sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file
(这会在行插入代码之后创建一个循环,它只循环遍历文件的其余部分,永远不会再次返回第一个sed命令) .
您可能会注意到我在匹配模式中添加了“^ *”,以防该行显示在注释中,比如说或缩进 . 它不是100%完美,但涵盖了其他一些可能很常见的情况 . 根据需要调整......
这两个解决方案也解决了问题(对于添加线的通用解决方案),如果你的新插入行包含未转义的反斜杠或者&符号,它们将被sed解释并且可能不会相同,就像 \n 一样 - 例如 . \0 将是匹配的第一行 . 特别方便的话,如果你以前必须先使用$ {var //}或其他sed语句等来逃避所有事情 .
\n
\0
这个解决方案在脚本中不那么混乱(引用和\ n不容易阅读),当你不想在行的开头放置a命令的替换文本时,如果在一个函数中带有缩进的线条 . 我已经利用shell将$'\ n'评估为换行符,而不是常规'\ n'单引号值 .
虽然我认为perl /甚至awk可能会因为更具可读性而获胜,但它已经足够长了 .
我有类似的任务,并且无法使上述perl解决方案起作用 .
这是我的解决方案:
perl -i -pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf
Explanation:
使用正则表达式在我的/etc/mysql/my.cnf文件中搜索仅包含 [mysqld] 的行,并将其替换为
[mysqld]
[mysqld] collation-server = utf8_unicode_ci
在包含 [mysqld] 的行之后有效添加 collation-server = utf8_unicode_ci 行 .
collation-server = utf8_unicode_ci
我最近不得不处理这个,但不仅仅是一个文件,而是多个不同的文件,我不能手工完成 . 所以我必须为它找到一个脚本 .
脚本下载:kinglazy-autoinsert.sh
Usage:
kinglazy-autoinsert.sh(list_file)(pattern_file)
Explanation of parameters:
list_file =这是包含要编辑的文件列表的绝对路径的文件
pattern_file =这是您指定要在其下添加新文本的模式(在第一列中)的文件 . 要在模式下添加的新文本在第二列中指定 . 这就是它!
该脚本可以节省时间并帮助您尽可能轻松地完成工作 .
依赖性:无
也许为此发布一个答案有点晚了,但我发现上面的一些解决方案有点麻烦 .
我在sed中尝试过简单的字符串替换,它起作用了:
sed 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file
& 符号反映匹配的字符串,然后添加\ n和新行 .
如上所述,如果您想要就地执行此操作:
sed -i 's/CLIENTSCRIPT="foo"/&\nCLIENTSCRIPT2="hello"/' file
另一件事 . 您可以使用表达式进行匹配:
sed -i 's/CLIENTSCRIPT=.*/&\nCLIENTSCRIPT2="hello"/' file
希望这有助于某人
7 回答
尝试使用GNU sed执行此操作:
如果你想在原地替换,请使用
输出
Doc
\a
(追加)注意标准
sed
语法(如在POSIX中,因此所有符合sed
实现的支持(GNU,OS / X,BSD,Solaris ...)):或者在一条线上:
(
-e
xpressions(以及-f
iles的内容)与换行符一起组成sed脚本sed
解释) .用于就地编辑的
-i
选项也是GNU扩展,其他一些实现(如FreeBSD)支持-i ''
.或者,为了便于携带,您可以使用
perl
代替:或者您可以使用
ed
或ex
:符合POSIX标准的使用
s
命令:Sed命令适用于MacOS(至少OS 10)和Unix一样(即不需要像Gilles(目前接受)那样的gnu sed):
这适用于bash以及其他可能知道$'\ n'评估报价样式的shell . 一切都可以在一行上,并在旧的/ POSIX sed命令中工作 . 如果可能有多行与CLIENTSCRIPT =“foo”(或您的等效符号)匹配,并且您希望第一次只添加额外的行,则可以按如下方式重做:
(这会在行插入代码之后创建一个循环,它只循环遍历文件的其余部分,永远不会再次返回第一个sed命令) .
您可能会注意到我在匹配模式中添加了“^ *”,以防该行显示在注释中,比如说或缩进 . 它不是100%完美,但涵盖了其他一些可能很常见的情况 . 根据需要调整......
这两个解决方案也解决了问题(对于添加线的通用解决方案),如果你的新插入行包含未转义的反斜杠或者&符号,它们将被sed解释并且可能不会相同,就像
\n
一样 - 例如 .\0
将是匹配的第一行 . 特别方便的话,如果你以前必须先使用$ {var //}或其他sed语句等来逃避所有事情 .这个解决方案在脚本中不那么混乱(引用和\ n不容易阅读),当你不想在行的开头放置a命令的替换文本时,如果在一个函数中带有缩进的线条 . 我已经利用shell将$'\ n'评估为换行符,而不是常规'\ n'单引号值 .
虽然我认为perl /甚至awk可能会因为更具可读性而获胜,但它已经足够长了 .
我有类似的任务,并且无法使上述perl解决方案起作用 .
这是我的解决方案:
perl -i -pe "BEGIN{undef $/;} s/^\[mysqld\]$/[mysqld]\n\ncollation-server = utf8_unicode_ci\n/sgm" /etc/mysql/my.cnf
Explanation:
使用正则表达式在我的/etc/mysql/my.cnf文件中搜索仅包含
[mysqld]
的行,并将其替换为[mysqld] collation-server = utf8_unicode_ci
在包含
[mysqld]
的行之后有效添加collation-server = utf8_unicode_ci
行 .我最近不得不处理这个,但不仅仅是一个文件,而是多个不同的文件,我不能手工完成 . 所以我必须为它找到一个脚本 .
脚本下载:kinglazy-autoinsert.sh
Usage:
kinglazy-autoinsert.sh(list_file)(pattern_file)
Explanation of parameters:
list_file =这是包含要编辑的文件列表的绝对路径的文件
pattern_file =这是您指定要在其下添加新文本的模式(在第一列中)的文件 . 要在模式下添加的新文本在第二列中指定 . 这就是它!
该脚本可以节省时间并帮助您尽可能轻松地完成工作 .
依赖性:无
也许为此发布一个答案有点晚了,但我发现上面的一些解决方案有点麻烦 .
我在sed中尝试过简单的字符串替换,它起作用了:
& 符号反映匹配的字符串,然后添加\ n和新行 .
如上所述,如果您想要就地执行此操作:
另一件事 . 您可以使用表达式进行匹配:
希望这有助于某人