複数のファイルを連結するが、セクションヘッダーとしてファイル名を含める


352

ターミナルで複数のテキストファイルを1つの大きなファイルに連結したいと思います。catコマンドを使用してこれを実行できることを知っています。ただし、各ファイルのファイル名は、そのファイルの「データダンプ」の前に付けたいと思います。誰でもこれを行う方法を知っていますか?

私が現在持っているもの:

file1.txt = bluemoongoodbeer

file2.txt = awesomepossum

file3.txt = hownowbrowncow

cat file1.txt file2.txt file3.txt

望ましい出力:

file1

bluemoongoodbeer

file2

awesomepossum

file3

hownowbrowncow

私は実際にuuencodeとuudecodeを使用して同様のことをしていますが、その間にファイルを読み取る必要はありません。結果が必要であり、それらを別のコマンドに再度パイプするだけです

回答:


531

同じことを探していて、これが示唆していることがわかりました:

tail -n +1 file1.txt file2.txt file3.txt

出力:

==> file1.txt <==
<contents of file1.txt>

==> file2.txt <==
<contents of file2.txt>

==> file3.txt <==
<contents of file3.txt>

ファイルが1つしかない場合、ヘッダーは印刷されません。GNU utilsを使用-vしている場合は、を使用して常にヘッダーを印刷できます。


2
これは、GNUテール(GNU Coreutilsの一部)でも機能します。
ArjunShankar

7
素晴らしい-n +1オプション!代替:head -n-0 file1 file2 file3
Frozen Flame

2
あなたが間にスペースを残すことができますBSDテールとMacOSのX上GNUテイルの両方で素晴らしい作品-n+1、のように-n+1
vdm 2017年

4
tail -n +1 *まさに探していたものでした、ありがとう!
kR105 2018年

1
MacOsX 10.14.4で動作しますsudo ulimit -n 1024; find -f . -name "*.rb" | xargs tail -n+1 > ./source_ruby.txt
kolas

186

私は同様のものにgrepを使用しました:

grep "" *.txt

それはあなたに「ヘッダー」を与えませんが、すべての行の前にファイル名を付けます。


10
*.txt1つのファイルのみに展開すると、出力が壊れます。この点に関して、私は助言しますgrep '' /dev/null *.txt
antak '10 / 07/14

1
grepの新しい使い方を見せてくれた+1。これは私のニーズを完全に満たしました。それは私に簡単に解析可能だっきちんとフォーマットされた出力を与えたので、私の場合には、各ファイルは、1行が含まれて
verboze

9
grep複数のファイルがある場合にのみ、ファイルヘッダーを印刷します。常にファイルパスを印刷する場合は、を使用します-H。ヘッダーが不要な場合は、を使用してください-h。また(standard input)、STDINの場合は印刷されます。
ホルヘブカラン2015

1
ag(シルバーサーチャー)を使用することもできます。デフォルトでは、ag . *.txt各ファイルの名前にプレフィックスを付け、各行に番号を付けます。
アルコール2016

1
注目すべきことに、-ngrep に渡すと、行番号も得られます。これにより、たとえばemacsで取得できるピンポイントで簡単なリンターを記述できます。
DepressedDaniel 2017年

104

これもうまくいくはずです:

find . -type f -print -exec cat {} \;

手段:

find    = linux `find` command finds filenames, see `man find` for more info
.       = in current directory
-type f = only files, not directories
-print  = show found file
-exec   = additionally execute another linux command
cat     = linux `cat` command, see `man cat`, displays file contents
{}      = placeholder for the currently found filename
\;      = tell `find` command that it ends now here

さらに、-andまたはのようなブール演算子を使用して検索を組み合わせることができます-orfind -lsいいですね。


1
このコマンドの機能について詳しく説明していただけますか?まさに私が必要としていたもの
AAlvz

4
これはLinuxの標準的なfindコマンドです。現在のディレクトリ内のすべてのファイルを検索し、それらの名前を出力してから、ファイルごとにcatします。を省略する-printと、の前にファイル名が出力されませんcat
Maxim_united 2014

17
を使用-printfして出力をカスタマイズすることもできます。例:find *.conf -type f -printf '\n==> %p <==\n' -exec cat {} \;tail -n +1 *
Maxim_united 2014

1
-の代わりにbrew install findutils使用したい場合を除き、-printfはMacでは機能しません。gfindfind
Matt Fletcher、

1
あなたは色をしたい場合は、その事実を使用することができfind、複数のことができ-execます。■find -name '*.conf' -exec printf '\n\e[33;1m%s\e[0m\n' {} \; -exec cat {} \;
banbh

24

これでうまくいくはずです:

for filename in file1.txt file2.txt file3.txt; do
    echo "$filename"
    cat "$filename"
done > output.txt

または、すべてのテキストファイルに対してこれを再帰的に行うには:

find . -type f -name '*.txt' -print | while read filename; do
    echo "$filename"
    cat "$filename"
done > output.txt

1
うまくいきませんでした。私は本当に醜いawkコードをいくつか書いたところです:$ listoffilesのi for awk '{print FILENAME、$ 0、$ 1、$ 2、$ 3、$ 4、$ 5、$ 6、$ 7、$ 8、$ 9、$ 10、$ 11}' $ i >> concat.txt完了
Nick

2
...詳しく説明しますか?これは、bashコードと同じくらい簡単です。
Chris Eberle、

@Nick:awk行は機能しないはず$0です。それが行全体であることを考えると、実際にはそこに列が繰り返されています...
Chris Eberle

@Nick:それ以外の場合はニフティソリューション:)
Chris Eberle

@クリス:はい、でも私が望んでいるよりずっと醜いです。>>を使用してstdoutをキャッチしているため、コードが機能していない可能性がありますか?
ニック

17

ファイル名と連結したいstats.txtで終わる一連のファイルがありました。

次のようにしました。複数のファイルがある場合、「more」コマンドはファイル名をヘッダーとして含めます。

more *stats.txt > stats.txt

または一般的な場合

more FILES_TO_CONCAT > OUTPUT_FILE

6
more <FILES> | cat
Acumenus 2014

15
find . -type f -print0 | xargs -0 -I % sh -c 'echo %; cat %'

これにより、完全なファイル名(パスを含む)が出力され、次にファイルの内容が出力されます。また、検索コマンドに-name "expr"を使用して、ファイルに対して好きなだけコマンドを実行できるため、非常に柔軟です。


1
と組み合わせるのも非常に簡単grepです。で使用するにはbashfind . -type f -print | grep PATTERN | xargs -n 1 -I {} -i bash -c 'echo ==== {} ====; cat {}; echo'
dojuba

5

このオプションが好き

for x in $(ls ./*.php); do echo $x; cat $x | grep -i 'menuItem'; done

出力は次のようになります。

./debug-things.php
./Facebook.Pixel.Code.php
./footer.trusted.seller.items.php
./GoogleAnalytics.php
./JivositeCode.php
./Live-Messenger.php
./mPopex.php
./NOTIFICATIONS-box.php
./reviewPopUp_Frame.php
            $('#top-nav-scroller-pos-<?=$active**MenuItem**;?>').addClass('active');
            gotTo**MenuItem**();
./Reviews-Frames-PopUps.php
./social.media.login.btns.php
./social-side-bar.php
./staticWalletsAlerst.php
./tmp-fix.php
./top-nav-scroller.php
$active**MenuItem** = '0';
        $active**MenuItem** = '1';
        $active**MenuItem** = '2';
        $active**MenuItem** = '3';
./Waiting-Overlay.php
./Yandex.Metrika.php

4

これは私が通常そのようなフォーマットを処理する方法です:

for i in *; do echo "$i"; echo ; cat "$i"; echo ; done ;

私は通常、特定の情報を得るために猫をgrepにパイプします。


3
ここで注意してください。for i in *サブディレクトリは含まれません。
Acumenus 2014年


3

forループを使用する代わりに、この単純なコマンドを使用できます。

ls -ltr | awk '{print $9}' | xargs head

3

色が好きなら、これを試してください:

for i in *; do echo; echo $'\e[33;1m'$i$'\e[0m'; cat $i; done | less -R

または:

tail -n +1 * | grep -e $ -e '==.*'

または:( 'multitail'パッケージがインストールされている場合)

multitail *

1
ファイル名を強調する色のために:find . -type f -name "*.txt" | xargs -I {} bash -c "echo $'\e[33;1m'{}$'\e[0m';cat {}"
MediaVince

3

すべてのファイルが同じ名前であるかfind、で照合できる場合、次のようにできます(例):

find . -name create.sh | xargs tail -n +1

検索するには、各ファイルのパスとcatを表示します。


2

これは本当に簡単な方法です。あなたは猫を飼いたいと言った、それはあなたがファイル全体を見たいと思っていることを意味する。ただし、ファイル名も印刷する必要があります。

これを試して

head -n99999999 * または head -n99999999 file1.txt file2.txt file3.txt

それが役に立てば幸い


4
クリーナーの構文は次のようになりますhead -n -0 file.txt file2.txt file3.txtheadGNU coreutils で動作します
doubleDown

1

このメソッドは、ファイル名とファイルの内容を出力します。

tail -f file1.txt file2.txt

出力:

==> file1.txt <==
contents of file1.txt ...
contents of file1.txt ...

==> file2.txt <==
contents of file2.txt ...
contents of file2.txt ...

3
-fあなたがではなく、実際にOPが尋ねたものの範囲内に書き込まれているファイルを追跡したい場合に便利です。
tripleee

1

これらの醜い==> <==を他のもので置き換えたい場合

tail -n +1 *.txt | sed -e 's/==>/\n###/g' -e 's/<==/###/g' >> "files.txt"

説明:

tail -n +1 *.txt -ヘッダー付きのフォルダー内のすべてのファイルを出力する

sed -e 's/==>/\n###/g' -e 's/<==/###/g'-交換する==>、新しい行 + ###<==だけで###

>> "files.txt" -すべてをファイルに出力



0

希望する出力と同じ形式の結果が必要な場合は、次のことを試してください。

for file in `ls file{1..3}.txt`; \
do echo $file | cut -d '.' -f 1; \ 
cat $file  ; done;

結果:

file1
bluemoongoodbeer
file2
awesomepossum
file3
hownowbrowncow

echo -eカットの前後に置くことができるので、ライン間の間隔も確保できます。

$ for file in `ls file{1..3}.txt`; do echo $file | cut -d '.' -f 1; echo -e; cat $file; echo -e  ; done;

結果:

file1

bluemoongoodbeer

file2

awesomepossum

file3

hownowbrowncow

説明:forループは、lsコマンドが生成したリストを通過します。$ ls file{1..3}.txt結果:file1.txt file2.txt file3.txt各繰り返しはします文字列は、それがにパイプの私が使用するコマンド(フィールド2がTXTである)フィールド1から2つの作品や版画にfileX.txtを破るフィールドセパレータとして残りは明らかであるecho$filecut.
Feketeシュメール

0
  • AIX 7.1 ksh

... 頭ですでに言及している人にうっとりしている人もいます。

$ r head
head file*.txt
==> file1.txt <==
xxx
111

==> file2.txt <==
yyy
222
nyuk nyuk nyuk

==> file3.txt <==
zzz
$

私の必要は最初の行を読むことです。前述のように、10行を超える場合は、オプション(ヘッド-9999など)を追加する必要があります。

派生コメントを投稿してすみません。誰かのコメントにコメント/追加するのに十分な通りの信用がありません。


-1

このタスクを解決するには、通常、次のコマンドを使用します。

$ cat file{1..3}.txt >> result.txt

これは、ファイルの数が非常に多い場合に、ファイルを連結するのに非常に便利な方法です。


1
しかし、これはOPの質問には答えません。
kvantour

-3

最初に各ファイルを作成しました:echo 'information'> file1.txt for each file [123] .txt。

次に、各ファイルを印刷して、情報が正しいことを確認しました:末尾ファイル?.txt

それから私はこれをしました:テールファイル?.txt >> Mainfile.txt。これにより、各ファイルの情報をメインファイルに格納するMainfile.txtが作成されました。

cat Mainfile.txtは、問題がないことを確認しました。

==> file1.txt <== bluemoongoodbeer

==> file2.txt <== awesomepossum

==> file3.txt <== hownowbrowncow

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