新しいファイルを作成しなくても、CLIのファイルの先頭にいくつかのテキストを追加できますか?

新しいファイルを作成しなくても、CLIのファイルの先頭にいくつかのテキストを追加できますか?

file1以下を含む2つのファイルがあります。

hello world
hello bangladesh  

そしてfile2以下を含みます -

 Dhaka in Bangladesh
 Dhaka is capital of Bangladesh  

次に更新したいと思いますfile2。 -

hello world
hello bangladesh 
Dhaka in Bangladesh
Dhaka is capital of Bangladesh

これは -

cat file1 file2 >> file3
mv file3 file2  

しかし、新しいファイルを作成したくありません。sed活用ができないかと思いました。

答え1

もちろん可能です。

(ほとんどすべてのテキストエディタが機能する方法なので、「内部」で一時ファイルを生成する可能性を心配しない限り、背後で一時ファイルを生成する可能性を避けることは完全に不可能であるとは言いませんが、この回答はカバーしません。)

printf '%s\n' '0r file1' x | ex file2

これはPOSIX準拠のコマンドです。ex, POSIX 指定非視覚的先行者vi

printfこれはエディタにコマンドを提供するためにのみ使用されます。出力はprintf次のとおりです

0r file1
x

x保存してください。

r「指定されたファイルの内容を読む」です。

0読み取ったテキストを配置する必要がある行番号を指定します。

答え2

標準ツールを使用してファイルを変更する方法はあまりありません。これを行うように見えても、一時ファイル(GNUなどsed -i)を使用している可能性があります。

ex一方、次のことを行います。

 ex -n -c '0r file2' -c wq file1

exはラインエディタであり、vimそこで進化しているので、これらのコマンドは慣れているようです。と同じ操作0r filename:指定されたアドレス(行番号)の後に指定されたファイルを挿入します。ここで行番号は 0 で、1 行前の行を表す仮想の行です。したがって、ファイルは既存のテキストの前に挿入されます。:0r filenamevim

その後、wq保存して終了します。

これが「非常に壊れやすい」という以下の説明を見つけたら、塩を1粒ずつ受け入れます。これをスクリプトで使用するには、適切な前提条件検証(ファイルの存在、読み取り/書き込み可能など)を実行する必要があります。とにかく素晴らしいシナリオ作家がすることがまさにそれだ。

修正する:-n一時ファイルの生成を防ぐことに関するOPの懸念を解決するために何かを追加しました。実装がexこれの一部として実装されていると仮定すると(ほとんどの最新システムの場合と同様に)、このフラグは一般的なスワップファイルの生成を抑制します。vimvim

答え3

all=$( cat file1 file2 )
echo "$all" > file2

小さなファイルでのみ機能します。

答え4

Jasenの答えと同様に、これはユーティリティの基礎です。

パスワードスポンジパッケージにその他のユーティリティほとんどすべてのプログラム(外部プログラムでも)が適切な機能を持つように設計されています。デフォルトでは、STDINから入力を受け取り、収集された出力をファイル名に書き込みますが、リダイレクトしません。

アイデアが気に入って、実際のスポンジのように、ファイルの代わりにメモリにデータを収集する同様のタスクを作成しました。

これを説明するシェルスクリプトは次のとおりです。

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }

pl " Input files data2, data3:"
head data[23]
pe
ls -gGli data[23]

pl " Results, re-write file from memory, preserving inode:"
cat data[23] | ./absorb-memory-public data3
head -v data3
pe
ls -gGli data3

生産:

-----
 Input files data2, data3:
==> data2 <==
hello world
hello bangladesh 

==> data3 <==
Dhaka in Bangladesh
Dhaka is capital of Bangladesh  

1051395 -rw-r--r-- 1 30 Jan  7 08:58 data2
1052221 -rw-r--r-- 1 53 Jan  7 08:58 data3

-----
 Results, re-write file from memory, preserving inode:
==> data3 <==
hello world
hello bangladesh 
Dhaka in Bangladesh
Dhaka is capital of Bangladesh  

1052221 -rw-r--r-- 1 83 Jan  7 08:58 data3

コアPerlコードは非常に短いです(特にエラーチェックがない場合はエラーチェックを追加することが望ましいかもしれません)。

use warnings;
use strict;
use Carp;

# Avoid hang for argument matching "-version","--version", etc.
exit(0) if @ARGV && $ARGV[0] =~ /-version/;

my ( $file, $f, $memory );
$file = shift || croak("Need a filename.");

$/ = 0777;      # Slurp the entire STDIN
$memory = do { local $/; <> };

open( $f, ">", $file ) || die " Cannot open file \"$file\" for write.\n";

print $f "$memory";

次のシステムで実行されます。

OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.9 (jessie) 
bash GNU bash 4.3.30
perl 5.20.2

頑張って...乾杯、drl

関連情報