在bash中只覆盖文件的一部分

时间:2015-01-30 21:44:42

标签: bash

我似乎无法弄清楚如何覆盖文件的一部分。例如,

echo -n "abcdefghijklmnopqrstuvwxyz" > file
echo -n "1234567890" > file
cat file
1234567890

echo -n "abcdefghijklmnopqrstuvwxyz" > file
echo -n "1234567890" >> file
cat file
abcdefghijklmnopqrstuvwxyz1234567890

我如何获得

1234567890klmnopqrstuvwxyz

我最终会用两个文件做这个,但我也希望用字符串来显示这个概念。 dd会为此工作吗?

4 个答案:

答案 0 :(得分:3)

您可以使用Bash原语执行此操作,就像您提出的那样。无需外部程序。 >的问题在于它会导致目标文件被截断。相反,你应该打开文件同时阅读和写作;这使得Bash跳过了截断步骤。

echo -n "abcdefghijklmnopqrstuvwxyz" > temp.txt
exec 3<> temp.txt   # open file descriptor 3 for reading and writing
echo -n "1234567890" >&3  # write to fd3
exec 3<&-  # close fd3 for reading
exec 3>&-  # close fd3 for writing

在Bash here中了解您从未想过的有关I / O重定向的所有信息。

答案 1 :(得分:2)

您可以使用sed

$ echo -n "abcdefghijklmnopqrstuvwxyz" > file
$ sed -i "1s/^.\{10\}/1234567890/" file
$ cat file
1234567890klmnopqrstuvwxyz

或者,更一般地说(无需硬编码长度):

$ echo -n "abcdefghijklmnopqrstuvwxyz" > file
$ str="1234567890"
$ sed -i "1s/^.\{${#str}\}/$str/" file
$ cat file
1234567890klmnopqrstuvwxyz

答案 2 :(得分:2)

假设file2包含'1234567890'且file包含'abcdefghijklmnopqrstuvwxyz',您可以这样做:

> dd conv=notrunc if=file2 of=file

> cat file
1234567890klmnopqrstuvwxyz

答案 3 :(得分:1)

以下是使用tail的方法:

# write the inital file
echo -n "abcdefghijklmnopqrstuvwxyz" > file
# set the input string  variable (just for readability)
inp="1234567890";
# replace <length of inp> characters in original file
# by concatenating $inp with tail's output (need to add 1)
echo ${inp}$(tail -c +$((${#inp}+1)) file) > file

我认为当你需要一个文件的结尾时,应该始终考虑tail,这正是这个问题归结为的。