我希望您能够使用Shell脚本将多行文本插入到文件中。 假设我的输入文件内容为: input.txt:
abcd
accd
cdef
line
web
现在我需要在文件中的" cdef "一行后面插入四行内容。插入后,我的文件应该像这样更改:
abcd
accd
cdef
line1
line2
line3
line4
line
web
我应该使用Shell脚本进行上述插入操作。有人可以帮我吗?
另一个sed
,
sed '/cdef/r add.txt' input.txt
input.txt:
abcd
accd
cdef
line
web
add.txt:
line1
line2
line3
line4
测试:
sat:~# sed '/cdef/r add.txt' input.txt
abcd
accd
cdef
line1
line2
line3
line4
line
web
如果你想将更改应用于 input.txt
文件,则使用带有 sed
的 -i
。
sed -i '/cdef/r add.txt' input.txt
如果您想将正则表达式用作表达式,则必须使用-E
标记与sed
一起使用。sed -E '/RegexPattern/r add.txt' input.txt
使用GNU sed
:
sed "/cdef/aline1\nline2\nline3\nline4" input.txt
如果您的起点是:
abcd
accd
cdef
line
web
这将产生:
abcd
accd
cdef
line1
line2
line3
line4
line
web
如果你想直接将更改保存在文件中,请使用以下命令:
sed -i "/cdef/aline1\nline2\nline3\nline4" input.txt
sed
还不熟悉,但我真的很喜欢它的强大功能!如果你想先添加一个空白行,你需要在 append 命令之后转义反斜杠字符,像这样:sed "/cdef/a\\\nline1\nline2\nline3\nline4" input.txt
。虽然我不确定为什么要这样做,但如果有人能解释一下就太好了! - hdlcdef
时都插入该行*,有没有办法使其仅在第一次遇到 cdef
时插入,而不再插入? - CMCDragonkaised
没有像GNU sed
一样精确实现a
命令,所以上述内容在至少macOS 10.13中无法在MacOS中运行(参见https://unix.stackexchange.com/a/131940/230763) - Mike Lutzsed
命令与GNU sed
命令在处理-i
选项时有所不同。在MacOS上,-i
需要一个带有备份后缀的参数。您需要指定-i ''
。 - Craig Bucheksed '/^cdef$/r'<(
echo "line1"
echo "line2"
echo "line3"
echo "line4"
) -i -- input.txt
sed '/^cdef$/r' <(printf "%s\n" line{1..4}) -i -- input.txt
。 - Walter A<(...)
的文件描述符将在主机上创建而不是客户机上。使用/someline/a<added\ncontent>
方法更好,特别是如果您执行类似于sed "/someline/a$(echo 'here you can have newlines' | tr \\n @ | sed '\''s/@/\\n/g'\')" -i -- input.txt
的操作(这不是一个完整的示例,也没有经过适当测试,我现在没有时间,但这应该包括您所需的构建块)。 - Luc使用 awk
:
awk '/cdef/{print $0 RS "line1" RS "line2" RS "line3" RS "line4";next}1' input.txt
说明:
/.../
找到要插入的行print $0
打印当前行RS
是内置的 awk
变量,默认设置为 new-line
1
在末尾导致打印每个其他行。在它之前使用 next
可以防止当前行,因为您已经使用 print $0
打印了它。$ awk '/cdef/{print $0 RS "line1" RS "line2" RS "line3" RS "line4";next}1' input.txt
abcd
accd
cdef
line1
line2
line3
line4
line
web
若要对文件进行更改,您可以执行以下操作:
awk '...' input.txt > tmp && mv tmp input.txt
这里是基于@rindeal 解决方案的更通用的解决方案,它在MacOS/BSD上不起作用(/r
需要一个文件):
cat << DOC > input.txt
abc
cdef
line
DOC
$ cat << EOF | sed '/^cdef$/ r /dev/stdin' input.txt
line 1
line 2
EOF
# outputs:
abc
cdef
line 1
line 2
line
这可以用来将任何东西传输到给定位置的文件中:
$ date | sed '/^cdef$/ r /dev/stdin' input.txt
# outputs
abc
cdef
Tue Mar 17 10:50:15 CET 2020
line
此外,您可以添加多个命令以允许删除标记行 cdef
:
$ date | sed '/^cdef$/ {
r /dev/stdin
d
}' input.txt
# outputs
abc
Tue Mar 17 10:53:53 CET 2020
line
awk
将一些命令的输出插入到 input.txt
的中间。cat otherfile
、ls -l
或由 printf
生成的带有数字的 4 行。awk 'NR==FNR {a[NR]=$0;next}
{print}
/cdef/ {for (i=1; i <= length(a); i++) { print a[i] }}'
<(printf "%s\n" line{1..4}) input.txt
line1
line2
line3
line4
sed -i -e '/cdef/r insert.txt' input.txt
但是,如果在您的input.txt文件中PATTERN 'cdef'重复多次,并且您只想在第一次出现模式后添加来自'insert.txt'的行,则一个优美的解决方案是:
printf "%s\n" "/cdef/r insert.txt" w | ed -s input.txt
如果该模式仅在您的input.txt文件中出现一次,则两种解决方案都可以正常工作。基于 @rindeal 的 solution,但输入更易读
sed '/^cdef$/r'<(cat <<EOF
line1
line2
line3
line4
EOF
) -i -- input.txt
sed -i "4i line1\nline2\nline3\nline4" input.txt
如果您不想将更改就地保存到文件中,请删除“-i”:
sed "4i line1\nline2\nline3\nline4" input.txt
使用GNU的sed*
如果您从以下内容开始input.txt:
abcd
accd
cdef
line
web
这将产生:
abcd
accd
cdef
line1
line2
line3
line4
line
web
这个答案很容易理解
替换原始文件
FILENAME='app/Providers/AuthServiceProvider.php'
sed '/THEPATTERNYOUARELOOKINGFOR/Q' $FILENAME >>${FILENAME}_temp
cat << 'EOL' >> ${FILENAME}_temp
HERE YOU COPY AND
PASTE MULTIPLE
LINES, ALSO YOU CAN
//WRITE COMMENTS
AND NEW LINES
AND SPECIAL CHARS LIKE $THISONE
EOL
grep -A 9999 'THEPATTERNYOUARELOOKINGFOR' $FILENAME >>${FILENAME}_temp
mv ${FILENAME}_temp $FILENAME
cat << EOL >> ${FILENAME}_temp
this variable will expand: $variable1
EOL
/dev/stdin
读取。 - potongadd.txt
添加的行前添加4个空格? - Hudcdef
出现,那么它也会将add.txt
的内容粘贴到你的文件中100次 :( - RAM237