首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将行/文本添加到文件的开头

如何将行/文本添加到文件的开头
EN

Unix & Linux用户
提问于 2018-01-17 09:20:23
回答 6查看 8.1K关注 0票数 4

我们有以下示例文件:

代码语言:javascript
复制
tcpmux          1/tcp                           # TCP port service multiplexer
tcpmux          1/udp                           # TCP port service multiplexer
rje             5/tcp                           # Remote Job Entry
rje             5/udp                           # Remote Job Entry
echo            7/tcp
echo            7/udp
discard         9/tcp           sink null
discard         9/udp           sink null
systat          11/tcp          users
systat          11/udp          users
daytime         13/tcp
daytime         13/udp
qotd            17/tcp          quote
qotd            17/udp          quote
msp             18/tcp                          # Message send protocol (historic)
msp             18/udp                          # Message send protocol (historic)
chargen         19/tcp          ttytst source
chargen         19/udp          ttytst source

我们如何将下列行添加到文件的开头?

代码语言:javascript
复制
# The latest IANA port assignments can be gotten from
#       http://www.iana.org/assignments/port-numbers
# The Well Known Ports are those from 0 through 1023.
# The Registered Ports are those from 1024 through 49151
# The Dynamic and/or Private Ports are those from 49152 through 65535
#
# Each line describes one service, and is of the form:
#
# service-name  port/protocol  [aliases ...]   [# comment]

因此,该文件将类似于:

代码语言:javascript
复制
# The latest IANA port assignments can be gotten from
#       http://www.iana.org/assignments/port-numbers
# The Well Known Ports are those from 0 through 1023.
# The Registered Ports are those from 1024 through 49151
# The Dynamic and/or Private Ports are those from 49152 through 65535
#
# Each line describes one service, and is of the form:
#
# service-name  port/protocol  [aliases ...]   [# comment]
tcpmux          1/tcp                           # TCP port service multiplexer
tcpmux          1/udp                           # TCP port service multiplexer
rje             5/tcp                           # Remote Job Entry
rje             5/udp                           # Remote Job Entry
echo            7/tcp
echo            7/udp
discard         9/tcp           sink null
discard         9/udp           sink null
systat          11/tcp          users
systat          11/udp          users
daytime         13/tcp
daytime         13/udp
qotd            17/tcp          quote
qotd            17/udp          quote
msp             18/tcp                          # Message send protocol (historic)
msp             18/udp                          # Message send protocol (historic)
chargen         19/tcp          ttytst source
chargen         19/udp          ttytst source

简单的解决方案是将原始文件复制到file.bck,将新行附加到文件中,并将file.bck附加到文件中。

<#>But --这不是一个优雅的解决方案。

EN

回答 6

Unix & Linux用户

回答已采纳

发布于 2018-01-17 09:57:15

使用POSIX指定文件编辑器ex-at的相对优雅的解决方案最不优雅,因为this将处理任何 arbitrary内容,而不是依赖于特定的格式(尾随反斜杠)或特定的格式缺失。

代码语言:javascript
复制
printf '0r headerfile\nx\n' | ex file-with-contents

这将在ex中打开D3,在最上面读取headerfile的全部内容,然后将修改后的缓冲区保存回file-with-contents

如果性能是一个严重的问题,而且文件是巨大的,这对您来说可能不是正确的方法,但是(a)不存在将前面的数据添加到文件中的一般方式,和(b)我不期望您会经常编辑您的/etc/services文件。

一种稍微简洁的语法(我实际上是这样编码的):

代码语言:javascript
复制
printf '%s\n' '0r headerfile' x | ex file-with-contents

A更复杂但更收敛的代码将检查 services EXACTLY的开头是否与字节的 header**完全匹配,如果不匹配,则将** header <#>的全部内容放在 <#>services <#>and的前面,如下所示。

这是完全符合POSIX的。

代码语言:javascript
复制
dd if=services bs=1 count="$(wc -c < header)" 2>/dev/null |
  cmp -s - header ||
    printf '%s\n' '0r header' x |
      ex services

一个简单得多的版本,使用GNU cmp的S "-n“选项:

代码语言:javascript
复制
cmp -sn "$(wc -c 

当然,这两种方法都不够聪明,无法检查部分匹配,但这远远超出了简单内线的能力,因为猜测将在本质上涉及到。

票数 6
EN

Unix & Linux用户

发布于 2018-01-17 09:33:59

通常,你就是这么做的。文件前面的行很难,因为文件只是字节序列,所以您需要向前移动现有的数据,以便为新数据腾出空间,而且没有直接的方法(至少没有标准方法)。理论上,人们可能会想到一个基于可变长度记录的文件系统,您可以在开始时或在现有记录之间添加新记录,但实际上并非如此。

一些文件系统可以移动数据块,但是它们是固定大小的块,因此对于文本文件没有太多的用处,因为其中的行有可变的长度。

即使您执行像sed -iperl -i这样的操作,他们也会为此在幕后创建一个临时文件。

所以,不管它是否优雅,我都会选择:

代码语言:javascript
复制
cat prefix data > data.new && mv data.new data

对于几行代码,您可以使用(在GNU中):

代码语言:javascript
复制
sed -i.bak -e '1i first prefix line' -e '1i second prefix line'  data

但是,为要添加的每一行生成insert命令或添加反斜杠也不优雅。

票数 5
EN

Unix & Linux用户

发布于 2018-01-17 09:38:47

好的,我决定写一个答复,除了一个评论。

您可以使用i命令的sed如下:

代码语言:javascript
复制
sed -i '1i \
# The latest IANA port assignments can be gotten from\
#       http://www.iana.org/assignments/port-numbers\
# The Well Known Ports are those from 0 through 1023.\
# The Registered Ports are those from 1024 through 49151\
# The Dynamic and/or Private Ports are those from 49152 through 65535\
#\
# Each line describes one service, and is of the form:\
#\
# service-name  port/protocol  [aliases ...]   [# comment]' file

这是给GNU sed的。对于Mac上的sed,您需要使用sed -i '' -e ...,而对于POSIX sed,没有简单的方法可以执行。

票数 4
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/417724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档