我想使用shell脚本将多行插入到文件中。 让我们考虑一下我的输入文件内容是: 的 input.txt中:
abcd
accd
cdef
line
web
现在我必须在 input.txt 文件中的'cdef'行后插入四行。 插入我的文件后应该改变如下:
abcd
accd
cdef
line1
line2
line3
line4
line
web
我应该使用shell脚本进行上面的插入。任何人都可以帮助我吗?
答案 0 :(得分:80)
另一个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
答案 1 :(得分:30)
使用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
答案 2 :(得分:15)
sed '/^cdef$/r'<(
echo "line1"
echo "line2"
echo "line3"
echo "line4"
) -i -- input.txt
答案 3 :(得分:13)
使用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
答案 4 :(得分:1)
这个答案很容易理解
替换原始文件
FILENAME =&#39;应用程序/提供者/ AuthServiceProvider.php&#39;
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
答案 5 :(得分:1)
这是基于@rindeal solution的通用解决方案,在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
答案 6 :(得分:0)
我需要用最少的工具来模板化几个文件,对我来说,sed -e '/../r file.txt
上的问题是它仅在打印出其余匹配项后才追加文件,而不是替换它。 / p>
这不行(所有匹配项都被替换,模式匹配从同一点继续)
#!/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}
答案 7 :(得分:0)
您可以使用awk
在input.txt
的中间插入某些命令的输出。
要插入的行可以是cat otherfile
,ls -l
的输出,也可以是4行,其行号由printf
生成。
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
答案 8 :(得分:0)
如果你想用 bash 脚本来做到这一点,那很有用。
echo $password | echo 'net.ipv4.ping_group_range=0 2147483647' | sudo -S tee -a /etc/sysctl.conf
答案 9 :(得分:0)
假设您有一个名为“insert.txt”的文件,其中包含要添加的行:
line1
line2
line3
line4
如果您的 input.txt 文件中的 PATTERN 'cdef' 重复多次,并且您想在所有出现的 'cdef' 模式之后添加来自 'insert.txt' 的行,那么一个简单的解决方案是:>
sed -i -e '/cdef/r insert.txt' input.txt
但是,如果模式“cdef”在 input.txt 文件中重复多次,并且您想仅在模式第一次出现后添加“insert.txt”中的行,一个漂亮的解决方案是:>
printf "%s\n" "/cdef/r insert.txt" w | ed -s input.txt
如果该模式在 input.txt 文件中只出现一次,两种解决方案都可以正常工作。