我想使用Shell脚本在文件中插入多行。让我们考虑一下我的输入文件内容是: input.txt:
abcd
accd
cdef
line
web
现在,我必须在input.txt文件中的'cdef'行之后插入四行。插入我的文件后,应更改为:
abcd
accd
cdef
line1
line2
line3
line4
line
web
上面的插入我应该使用shell脚本来做。谁能帮我?
Answers:
另一个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
文件中的更改。然后,-i
与一起使用sed
。
sed -i '/cdef/r add.txt' input.txt
如果要将正则表达式用作表达式,则必须将-E
标记与一起使用sed
。
sed -E '/RegexPattern/r add.txt' input.txt
r
命令从中读取/dev/stdin
。
add.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
但哇,我爱上它的力量!如果你想添加一个空的换行首先你要逃避这样的附加命令后反斜杠字符:sed "/cdef/a\\\nline1\nline2\nline3\nline4" input.txt
。我不确定为什么它会那样工作,如果有人可以解释的话,那会很好!
cdef
,是否有办法使其仅在第一次遇到时才插入cdef
?
sed
不执行a
命令完全相同的GNU sed
,所以在MacOS上没有MODS以上将无法正常工作-至少10.13的MacOS(见unix.stackexchange.com/a/131940/230763)
使用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
这个答案很容易理解
替换原始文件
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
这是基于@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
我需要用最少的工具来模板化几个文件,对我来说,上面的问题sed -e '/../r file.txt
是它仅在打印出其余匹配项后才追加文件,而不是替换它。
这样做不会(替换所有匹配项,并且模式匹配从同一点继续)
#!/bin/bash
TEMPDIR=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")
# remove on exit
trap "rm -rf $TEMPDIR" EXIT
DCTEMPLATE=$TEMPDIR/dctemplate.txt
DCTEMPFILE=$TEMPDIR/dctempfile.txt
# template that will replace
printf "0replacement
1${SHELL} data
2anotherlinenoEOL" > $DCTEMPLATE
# test data
echo -e "xxy \n987 \nxx xx\n yz yxxyy" > $DCTEMPFILE
# print original for debug
echo "---8<--- $DCTEMPFILE"
cat $DCTEMPFILE
echo "---8<--- $DCTEMPLATE"
cat $DCTEMPLATE
echo "---8<---"
# replace 'xx' -> contents of $DCTEMPFILE
perl -e "our \$fname = '${DCTEMPLATE}';" -pe 's/xx/`cat $fname`/eg' ${DCTEMPFILE}