将文件的内容插入另一个文件(在发送的文件的特定行中)-BASH / LINUX

时间:2012-12-26 17:37:03

标签: linux bash shell

我尝试使用cat进行操作,然后在我输入第二个文件后添加了| head -$line | tail -1,但它不起作用,因为它首先执行cat

有什么想法吗?我需要使用cat或其他内容。

5 个答案:

答案 0 :(得分:20)

我可能会使用sed来完成这项工作:

line=3
sed -e "${line}r file2" file1

如果您要覆盖file1并且您拥有GNU sed,请添加-i选项。否则,写入临时文件,然后将临时文件复制/移动到原始文件上,根据需要进行清理(这是下面的trap内容)。注意:在文件上复制临时文件会保留链接;移动不会(但更快,特别是如果文件很大)。

line=3
tmp="./sed.$$"
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
sed -e "${line}r file2" file1 > $tmp
cp $tmp file1
rm -f $tmp
trap 0

答案 1 :(得分:7)

只是为了好玩,只因为我们都喜欢ed标准编辑器,这里是ed版本。这非常有效(ed正版文本编辑器)!

ed -s file2 <<< $'3r file1\nw'

如果行号存储在变量line中,则:

ed -s file2 <<< "${line}r file1"$'\nw'

为了取悦Zack,这是一个版本较少的版本,如果你不喜欢bash(个人而言,我不喜欢管道和子壳,我更喜欢herestrings,但是,嘿,正如我所说,这只是为了取悦扎克):

printf "%s\n" "${line}r file1" w | ed -s file2

或(为了取悦Sorpigal):

printf "%dr %s\nw" "$line" file1 | ed -s file2

正如Jonathan Leffler在评论中提到的,如果您打算在脚本中使用此方法,请使用heredoc(通常效率最高):

ed -s file2 <<EOF
${line}r file1
w
EOF

希望这有帮助!

P.S。如果您觉得需要表达自己驾驶ed标准编辑器的方法,请随时发表评论。

答案 2 :(得分:2)

cat file1 >>file2

会将file1的内容追加到file2。

cat file1 file2

将连接file1和file2并将输出发送到终端。

cat file1 file2 >file3

将创建或覆盖file3,并连接file1和file2

cat file1 file2 >>file3

会将file1和file2的连接追加到file3的末尾。

修改

在添加file1之前中继file2:

sed -e '11,$d' -i file2 && cat file1 >>file2

或制作500行文件:

n=$((500-$(wc -l <file1)))
sed -e "1,${n}d" -i file2 && cat file1 >>file2

答案 3 :(得分:2)

有很多方法可以做到,但我喜欢选择一种涉及制作工具的方式。

首先,设置测试环境

rm -rf /tmp/test
mkdir /tmp/test
printf '%s\n' {0..9} > /tmp/test/f1
printf '%s\n' {one,two,three,four,five,six,seven,eight,nine,ten} > /tmp/test/f2

现在让我们制作这个工具,在第一遍中,我们将严格执行它。

# insert contents of file $1 into file $2 at line $3
insert_at () { insert="$1" ; into="$2" ; at="$3" ; { head -n $at "$into" ; ((at++)) ; cat "$insert" ; tail -n +$at "$into" ; } ; }

然后运行该工具以查看惊人的结果。

$ insert_at /tmp/test/f1 /tmp/test/f2 5

但等等,结果是stdout!怎么覆盖原件?没问题,我们可以为此制作另一个工具。

insert_at_replace () { tmp=$(mktemp) ; insert_at "$@" > "$tmp" ; mv "$tmp" "$2" ; }

然后运行它

$ insert_at_replace /tmp/test/f1 /tmp/test/f2 5
$ cat /tmp/test/f2

“你的实施很糟糕!”

我知道,但这就是制作简单工具的美妙之处。让我们用sed版本替换insert_at

insert_at () { insert="$1" ; into="$2" ; at="$3" ; sed -e "${at}r ${insert}" "$into" ; }

insert_at_replace继续工作(当然)。 insert_at_replace的实现也可以改为减少错误,但我会将其作为读者的练习。

答案 4 :(得分:0)

如果您不介意管理新文件,我喜欢使用headtail进行此操作:

head -n 16 file1 >  file3 &&
cat        file2 >> file3 &&
tail -n+56 file1 >> file3
  

如果愿意,可以将其折叠为一行。然后,如果您真的需要它来覆盖file1,请执行:mv file3 file1(在命令之间可以选择包含&&)。

注意:

  • head -n 16 file1表示文件1的前16行
  • tail -n+56 file1表示file1从第56行开始到结尾
  • 因此,我实际上从file1跳过了第17至55行。
  • 当然,如果您可以将56更改为17,那么就不会跳过任何行。
  • 我更喜欢混合使用简单的headtail命令,然后尝试使用神奇的sed命令。