次のサンプルファイルがあります。
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
をファイルに追加することです。
しかし、これはエレガントな解決策ではありません。
POSIX指定のファイルエディタex
を使用した比較的エレガントなソリューション---これはany任意を処理するという意味で少なくともエレガントです内容特定の形式(末尾のバックスラッシュ)または特定の形式の欠如に依存するのではなく。
printf '0r headerfile\nx\n' | ex file-with-contents
これにより、ex
のfile-with-contents
が開き、最上部のheaderfile
の内容全体が読み込まれ、変更されたバッファがfile-with-contents
に保存されます。
パフォーマンスが深刻な問題であり、ファイルが巨大な場合、これは適切な方法ではない可能性がありますが、(a)prependデータをファイルに出力する一般的な方法はなく、(b)ありません/etc/services
ファイルを頻繁に編集することは期待できません。
少しすっきりした構文(実際にこれをコーディングする方法):
printf '%s\n' '0r headerfile' x | ex file-with-contents
services
の始まりがheader
全体と正確に一致するかどうかをチェックするコードのより複雑な、しかし収束的なビット、バイトごとに、そしてIF NOTが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
GNU cmp
の「-n」オプションを使用した、はるかに単純なバージョン:
cmp -sn "$(wc -c <header)" header services ||
printf '%s\n' '0r header' x | ex services
もちろん、どちらもPARTIALの一致をチェックするほどスマートではありませんが、推測は本質的に関与するため、単純なワンライナーの能力をはるかに超えています。
通常、あなたはそれをします。ファイルは単なるバイトのシーケンスであるため、ファイルの先頭に行を追加することは難しいため、既存のデータを先に移動して新しいデータ用のスペースを作る必要があり、そのための直接的な方法はありません(少なくとも標準的な方法はありません)。理論的には、可変長レコードに基づくファイルシステムを想像するかもしれません。そこでは、最初または既存のレコードの間に新しいレコードを追加できますが、実際にはそうではありません。
一部のファイルシステムはデータのブロックを移動できますが、それらは固定サイズのブロックであるため、行が可変長であるテキストファイルにはあまり使用されません。
sed -i
やPerl -i
のようなことをしたとしても、そのためにバックグラウンドで一時ファイルが作成されます。
だから、それがエレガントであろうとなかろうと、私は次のように行きます:
cat prefix data > data.new && mv data.new data
数行では、(GNU sed)で使用できます:
sed -i.bak -e '1i first prefix line' -e '1i second prefix line' data
ただし、挿入コマンドを生成したり、追加する行ごとにバックスラッシュを追加したりするのも、洗練されていません。
わかりましたコメント以外に答えを書くことにしました。
次のように、i
のsed
コマンドを使用できます。
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
があります。物事を適切に行う簡単な方法はありません。
別のアプローチ:ほとんどのLinuxディストリビューションで利用可能な moreutils パッケージのsponge
を使用して、次のこともできます
$ cat - file.txt | sponge file.txt
# 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]
これはcat
を使用して結合して、標準入力(-
)と元のファイル(file.txt
)を組み合わせて再現し、結合された出力をsponge
にパイプします。結果は同じ場所に同じファイルに戻ります。次に、ヘッダーをターミナルに貼り付け、Ctrl+D
で終了します。
または、ヘッダーを別のファイルに既に保存している場合は、
cat header.txt file.txt | sponge file.txt
同じ結果を達成するため。
結果を達成するために、sed one linerの下で使用されます。テストしたように、それはうまくいきました
疑問があれば教えてください
sed '1s/.*/\n&/g' examplefile| sed '1r file2.txt' | sed '1d'
examplefile ===>その入力ファイル
file2.txt ===>これは、examplefileの先頭に追加する必要があるコンテンツを含むファイルです