仅覆盖 bash 中的文件的一部分

Overwrite just a part of the file in 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 可以吗?

您可以使用 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

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

> dd conv=notrunc if=file2 of=file

> cat file
1234567890klmnopqrstuvwxyz

下面是使用 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 当你需要一个文件的结尾时,应该始终考虑,这就是这个问题的真正原因。

您可以使用 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 重定向的一切你不想知道的