[英]Insert multiple lines into a file after specified pattern using shell script
我想使用 shell 脚本将多行插入到一个文件中。 让我们考虑一下我的输入文件内容是: input.txt:
abcd
accd
cdef
line
web
现在我必须在input.txt文件中的“cdef”行之后插入四行。 插入我的文件后应该像这样改变:
abcd
accd
cdef
line1
line2
line3
line4
line
web
上面的插入我应该使用 shell 脚本来完成。 谁能帮我?
另一个sed
,
sed '/cdef/r add.txt' input.txt
输入.txt:
abcd
accd
cdef
line
web
添加.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
使用 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 '/^cdef$/r'<(
echo "line1"
echo "line2"
echo "line3"
echo "line4"
) -i -- input.txt
使用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
这个答案很容易理解
替换原文件
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
我需要用最少的工具来模板化一些文件,对我来说,上面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}
您可以使用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
如果你想用 bash 脚本来做到这一点,那很有用。
echo $password | echo 'net.ipv4.ping_group_range=0 2147483647' | sudo -S tee -a /etc/sysctl.conf
假设您有一个名为“insert.txt”的文件,其中包含要添加的行:
line1
line2
line3
line4
如果模式 'cdef' 在 input.txt 文件中重复多次,并且您想在所有出现的模式 'cdef' 之后添加来自 'insert.txt' 的行,那么一个简单的解决方案是:
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解决方案,但具有更好的输入可读性
sed '/^cdef$/r'<(cat <<EOF
line1
line2
line3
line4
EOF
) -i -- input.txt
将内容放在第 4 行(如你所愿)
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.