使用shell脚本在指定的模式后将多行插入到文件中

时间:2014-03-19 05:43:50

标签: linux bash shell sed awk

我想使用shell脚本将多行插入到文件中。 让我们考虑一下我的输入文件内容是: 的 input.txt中:

abcd
accd
cdef
line
web

现在我必须在 input.txt 文件中的'cdef'行后插入四行。 插入我的文件后应该改变如下:

abcd
accd
cdef
line1
line2
line3
line4
line
web

我应该使用shell脚本进行上面的插入。任何人都可以帮助我吗?

10 个答案:

答案 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文件中应用更改。然后,将-ised一起使用。

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;

STEP 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

STEP 3添加文件的其余部分

grep -A 9999 'THEPATTERNYOUARELOOKINGFOR' $FILENAME >>${FILENAME}_temp

REPLACE原始文件

mv ${FILENAME}_temp $FILENAME

如果您需要变量,请在步骤2中替换EOL&#39;与EOL

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)

您可以使用awkinput.txt的中间插入某些命令的输出。
要插入的行可以是cat otherfilels -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 文件中只出现一次,两种解决方案都可以正常工作。