ファイルの先頭に行/テキストを追加する方法

ファイルの先頭に行/テキストを追加する方法

次のサンプルファイルがあります。

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

ファイルの先頭に次の行を追加するにはどうすればよいですか?

# 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]

これにより、ファイルは次のように表示されます。

# 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追加することです。

しかし、これはエレガントな解決策ではありません。

ベストアンサー1

以下を使用する比較的エレガントなソリューションPOSIX固有のファイルエディタex-少なくとも、この意味ではエレガントこれが処理するでしょうどのすべてのコンテンツ特定の形式(末尾のバックスラッシュ)に依存したり、特定の形式がないわけではありません。

printf '0r headerfile\nx\n' | ex file-with-contents

その後、 が開き、file-with-contents最上位の内容全体を読み取り、変更されたexバッファが再び保存されます。headerfilefile-with-contents

パフォーマンスが深刻な問題でファイルが大きい場合、この方法は適切ではありませんが、(a)高性能のための普遍的な方法はありません。プレフィックス/etc/servicesデータをファイルに保存して(b)ファイルを編集できないようです。それ頻繁に。


ややクリーンな構文(実際にコーディングした方法):

printf '%s\n' '0r headerfile' x | ex file-with-contents

services以下は、最初の内容全体が正確に一致するかどうかをバイト単位で確認しheader、一致しない場合はその内容header全体を前に追加し、services変更を保存するより複雑ですが収束的なコードです。

これはPOSIXと完全に互換性があります。

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

cmpGNUの "-n"オプションを使用するより簡単なバージョン:

cmp -sn "$(wc -c <header)" header services ||
  printf '%s\n' '0r header' x | ex services

もちろん、これらのどれも部分的な一致を確認するほどスマートではありませんが、本質的に推測が含まれているので、単純な一行アプローチの機能をはるかに超えています。

おすすめ記事