シェルからLinuxで1つのファイルを別のファイルに追加する方法は?


418

との2つのファイルがfile1ありfile2ます。の内容をプロセスに永続化させるには、どのようにfile2to の内容を追加しますか?file1file1

回答:


611

bash組み込みリダイレクト(tldp)を使用します。

cat file2 >> file1

2
どうすれば宛先ファイルを所有しておらず、sudoを使用する必要がありますか?
Bijay Rungta 2014

1
@BijayRungta:あなた自身の質問に答えたようですね。コマンドの前に付加sudocatます(プロンプトが表示されたら資格情報を入力します)。
デビッド

あなたがする必要がある... chmod 777 / etc / default / dockerそのファイルへの書き込み許可を自分に与える
完了し

1
@Sigur:一度に2つのファイルに出力を送信する方法がない限り、コマンドを2回呼び出す必要があります。
デビッド

2
@Sigurまたはteeプログラムをご覧くださいcat 1 | tee -a 2 3--append(または-a略して)スイッチの後、好きなだけファイルを置くことができます。
Stefan van den Akker、2017年

291

cat file2 >> file1

>>オペレータは、名前のファイルに出力を追加したり、それが存在しない場合は名前のファイルを作成します。

cat file1 file2 > file3

これにより、2つ以上のファイルが1つに連結されます。必要な数のソースファイルを持つことができます。例えば、

cat *.txt >> newfile.txt

更新20130902
コメントで、eumiroは「試さないでくださいcat file1 file2 > file1」と提案しています。これが予期した結果にならない理由は、リダイレクトの受信ファイルが、左側のコマンド>が実行される前に準備されるためです。この場合、最初にfile1長さがゼロに切り捨てられて出力用に開かれ、次にcatコマンドは長さがゼロになったファイルとfile2into の内容を連結しようとしますfile1。その結果、の元のコンテンツfile1が失われ、代わりにそのコピーがfile2おそらく予期されたものとは異なります。

更新20160919
コメントで、tparteeはバッキング情報/ソースへのリンクを提案しています。信頼できるリファレンスとして、私は親切な読者にlinuxcommand.orgのshマニュアルページを紹介しています。

コマンドが実行される前に、シェルによって解釈される特別な表記法を使用して、その入力と出力をリダイレクトできます。

それは読者が知っておくべきことを読者に伝えますが、それを探しておらず、ステートメントを単語ごとに解析していないと見落としがちです。ここで最も重要な言葉は「前」です。コマンドが実行される前に、リダイレクトが完了(または失敗)します。

cat file1 file2 > file1シェルの例の場合、最初にリダイレクトを実行して、コマンドが実行される前にコマンドが実行される環境にI / Oハンドルが配置されるようにします。

Ian AllenのWebサイトには、リダイレクションの優先順位が詳細に説明されている、より使いやすいバージョンがLinuxコースウェアの形で用意されています。彼のI / O Redirection Notesページは、リダイレクトがコマンドなしでも機能するという観察を含め、このトピックについて多くのことを述べています。これをシェルに渡す:

$ >out

... outという名前の空のファイルを作成します。シェルは最初にI / Oリダイレクションを設定し、次にコマンドを探し、何も見つからず、操作を完了します。


17
@asir-しないでくださいcat file1 file2 > file1-これはおそらくあなたが待っているようには機能しません。
eumiro

5
実際、これはまさに彼が必要としていることです。「現在のファイルを上書きせずに」1と言います。最初の3つの回答は完全に質問のこの部分を無視して使用してコマンドを提案してき>>だろうファイルを変更しますfile1。T.Robは、実際には不正確な何かを提出するためにただ競争するのではなく、彼の答えを説明するはるかに優れた仕事をしました。質問のテキストに基づいて、私はそれcat file1 file2 > file3が@asirが探していた適切なコマンドだと思います。
dm78

親切な言葉をありがとう、デイビッド!@eumiroが上記で指摘しているが詳細には触れていないのは、の右側の操作が>最初に実行されることです。したがって、実行するcat file1 file2 > file1と最初にClobberが実行されfile1、次に長さがゼロになったファイルがそれ自体にコピーされます。これは、操作が発生する可能性のある順序と発生する順序を考えると理にかなっていますが、多くの人を驚かせるほど微妙です。ですから、eumiroとあなたは答えのさらなる改善を促しました。それをありがとう!
T.Rob

また、cat file1 >> file1を試さないでください。これにより、ファイルが再帰的に書き換えられます。誤ってこれを行うと、数秒以内に、数千行前から5,000万行がファイルに挿入されました。
Hendra Uzia 2017年

また、もう少し簡潔にするために、「新しいファイル」がすでに存在する場合>> 、ファイルに追加してファイルを> 置き換えます。
rinogo 2018

43

sudoを使用する必要がある場合は、次のようにします。

sudo bash -c 'cat file2 >> file1'

sudo特権の昇格は出力のリダイレクトに引き継がれないため、コマンドの先頭に追加する通常の方法は失敗します。


6
これの別の一般的なイディオムは次のcat file2 | sudo tee -a file1 > /dev/null
とおり


13

参考までに、たとえば、大きなファイルがあり、一時停止して後で実行する必要がある場合、ddrescueを使用すると、タスクを中断できる方法で実行できます。

ddrescue -o $(wc --bytes file1 | awk '{ print $1 }') file2 file1 logfile

logfile重要なビットです。Ctrl-Cまったく同じコマンドを再度指定することで、プロセスを中断して再開できます。ddrescueは、中断したlogfileところから読み取り、再開します。この-o Aフラグは、出力ファイル()のバイトAから開始するようにddrescueに指示しますfile1。したがって、バイト単位wc --bytes file1 | awk '{ print $1 }'のサイズを抽出するだけfile1です(必要にls応じて、出力から貼り付けることができます)。

コメントでngksが指摘したように、欠点はddrescueがデフォルトでインストールされない可能性が高いため、手動でインストールする必要があることです。もう1つの問題は、リポジトリにある可能性があるddrescueの2つのバージョンがあることです。詳細については、このaskubuntuの質問を参照してください。必要なバージョンはGNU ddrescueで、Debianベースのシステムでは次の名前のパッケージgddrescueです。

sudo apt install gddrescue

他のディストリビューションについては、パッケージ管理システムでddrescueのGNUバージョンを確認してください。


1
新規ユーザーのために:ddrescueはGNUツールですが、Linux、Mac、またはその他のUNIXライクなシステムには存在しない場合があります。ddrescueは、POSIXまたはその他の標準で必要とされていないようです。

2

別の解決策:

cat file1 | tee -a file2

tee たとえば、次のように、好きなだけファイルに追加できるという利点があります。

cat file1 | tee -a file2 file3 file3

内容追加しますfile1にしfile2file3そしてfile4

manページから:

-a, --append
       append to the given FILEs, do not overwrite

0

cat簡単な解決策になる可能性がありますが、大きなファイルを連結すると非常に遅くなりますfind -print。猫を一度使用する必要がありますが、あなたを救うことです。

amey@xps ~/work/python/tmp $ ls -lhtr
total 969M
-rw-r--r-- 1 amey amey 485M May 24 23:54 bigFile2.txt
-rw-r--r-- 1 amey amey 485M May 24 23:55 bigFile1.txt

 amey@xps ~/work/python/tmp $ time cat bigFile1.txt bigFile2.txt >> out.txt

real    0m3.084s
user    0m0.012s
sys     0m2.308s


amey@xps ~/work/python/tmp $ time find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1

real    0m2.516s
user    0m0.028s
sys     0m2.204s

find / catコンボコマンドについて報告する時間の節約は、ファイルの名前を出力するfindコマンドのみのタイミングを取っているためです。このようにコマンド全体のタイミングを調整してみてくださいtime (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1)。猫だけのコマンドと同様の結果が得られるはずです。
JoshMc 2017年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.