使用 shell 脚本在指定模式后将多行插入到文件中
- 2024-10-31 08:38:00
- admin 原创
- 43
问题描述:
我想使用 shell 脚本将多行插入到文件中。假设我的输入文件内容为:
input.txt:
abcd
accd
cdef
line
web
现在我必须在input.txt文件中的“cdef”行后插入四行。插入后我的文件应该会像这样改变:
abcd
accd
cdef
line1
line2
line3
line4
line
web
我应该使用 shell 脚本进行上述插入。有人能帮助我吗?
解决方案 1:
其他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
with sed
。
sed -i '/cdef/r add.txt' input.txt
如果您想使用正则表达式作为表达式,则必须使用-E
带有 的标签sed
。
sed -E '/RegexPattern/r add.txt' input.txt
解决方案 2:
使用 GNU sed
:
sed "/cdef/aline1
line2
line3
line4" input.txt
如果你从以下开始:
abcd
accd
cdef
line
web
这将产生:
abcd
accd
cdef
line1
line2
line3
line4
line
web
如果你想将更改保存到文件原位,请说:
sed -i "/cdef/aline1
line2
line3
line4" input.txt
解决方案 3:
sed '/^cdef$/r'<(
echo "line1"
echo "line2"
echo "line3"
echo "line4"
) -i -- input.txt
解决方案 4:
使用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
解决方案 5:
这是一个基于@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
解决方案 6:
基于@rindeal解决方案,但输入的可读性更好
sed '/^cdef$/r'<(cat <<EOF
line1
line2
line3
line4
EOF
) -i -- input.txt
解决方案 7:
您可以使用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
" line{1..4}) input.txt
解决方案 8:
这个答案很容易理解
图案前复制
添加线条
按照图案复制
替换原文件
FILENAME ='app/Providers/AuthServiceProvider.php'
步骤 1 复制,直到图案
sed '/THEPATTERNYOUARELOOKINGFOR/Q' $FILENAME >>${FILENAME}_temp
步骤 2 添加线条
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
步骤 3 添加文件的其余部分
grep -A 9999 'THEPATTERNYOUARELOOKINGFOR' $FILENAME >>${FILENAME}_temp
替换原始文件
mv ${FILENAME}_temp $FILENAME
如果你需要变量,请在步骤 2 中将“EOL”替换为 EOL
cat << EOL >> ${FILENAME}_temp
this variable will expand: $variable1
EOL
解决方案 9:
假设您有一个名为“insert.txt”的文件,其中包含您要添加的行:
line1
line2
line3
line4
如果模式“cdef”在您的 input.txt 文件中重复多次,并且您想要在模式“cdef”的所有出现之后添加“insert.txt”中的行,那么一个简单的解决方案是:
sed -i -e '/cdef/r insert.txt' input.txt
但是,如果模式“cdef”在您的 input.txt 文件中重复多次,并且您只想在模式第一次出现之后添加“insert.txt”中的行,那么一个漂亮的解决方案是:
`printf "%s
" "/cdef/r insert.txt" w | ed -s input.txt`
如果该模式在您的 input.txt 文件中只出现一次,这两种解决方案都可以正常工作。
解决方案 10:
将内容放在第四行(如您所愿)
sed -i "4i line1
line2
line3
line4" input.txt
如果您不想保存对文件的更改,请删除“-i”:
sed "4i line1
line2
line3
line4" input.txt
使用 GNU* 的 sed
如果你使用以下命令启动 input.txt:
abcd
accd
cdef
line
web
这将产生:
abcd
accd
cdef
line1
line2
line3
line4
line
web
解决方案 11:
我需要使用最少的工具来模板化一些文件,而对于我来说,上述问题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
987
xx xx
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}
解决方案 12:
如果你想用 bash 脚本来做到这一点,那很有用。
echo $password | echo 'net.ipv4.ping_group_range=0 2147483647' | sudo -S tee -a /etc/sysctl.conf
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件