串联多个文件,但将文件名包含为节标题


352

我想在终端中将多个文本文件连接成一个大文件。我知道我可以使用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做类似的事情,我不需要中间的文件可读性,只需要结果并将它们再次通过管道传递给另一个命令

Answers:


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>

如果只有一个文件,则不会打印标题。如果使用GNU utils,则可以使用-v始终打印标题。


2
这也适用于GNU尾部(GNU Coreutils的一部分)。
ArjunShankar

7
很棒的-n +1选择!替代方法:head -n-0 file1 file2 file3
冰雪奇缘》 2015年

2
伟大的作品既BSD尾巴和GNU尾MacOS X上你可以之间留出的空间-n+1,如-n+1
vdm

4
tail -n +1 *正是我在找,谢谢!
kR105

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
如果*.txt仅扩展到一个文件,则输出中断。在这方面,我建议grep '' /dev/null *.txt
antak 2014年

1
+1为我展示了grep的新用法。这完全满足了我的需求。以我
为例

9
grep如果文件多于一个,则仅打印文件头。如果要确保始终打印文件路径,请使用-H。如果您不希望标题使用-h。另请注意,它将(standard input)以STDIN 打印。
Jorge Bucaran 2015年

1
您还可以使用ag(银色搜索器):默认情况下,ag . *.txt每个文件都以其名称作为前缀,每行以其编号作为前缀。
酒精

1
值得注意的是,传递-n给grep还会产生行号,该行号使您可以编写简单的linters并可以被emacs识别。
DepressedDaniel

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命令。它搜索当前目录中的所有文件,打印它们的名称,然后为每个文件命名。省略-print不会在之前打印文件名cat
Maxim_united 2014年

17
您也可以使用-printf来自定义输出。例如:find *.conf -type f -printf '\n==> %p <==\n' -exec cat {} \;匹配tail -n +1 *
Maxim_united 2014年

1
-printf在Mac上不起作用,除非您想要brew install findutils然后再使用gfind而不是find
马特·弗莱彻

1
如果您想要颜色,则可以使用find允许多个-execs的事实: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中,我为awk'{print FILENAME,$ 0,$ 1,$ 2,$ 3,$ 4,$ 5,$ 6,$ 7,$ 8,$ 9,$ 10,$ 11}'$ i >> concat.txt完成
尼克,

2
...要详细说明吗?这几乎与bash代码一样简单。
克里斯·埃伯勒

@Nick:考虑到$0整个行,awk行甚至都行不通,因此您实际上在那里重复了一些列……
Chris Eberle

@Nick:否则为Nifty解决方案:)
Chris Eberle

@Chris:是的,但是比我想要的要难看得多。也许您的代码对我不起作用,因为我使用>>来捕获标准输出?
尼克

17

我有一系列以stats.txt结尾的文件,希望与文件名连接。

我执行了以下操作,当有多个文件时,“更多”命令将文件名作为标题。

more *stats.txt > stats.txt

或一般情况

more FILES_TO_CONCAT > OUTPUT_FILE

5
more <FILES> | cat
Acumenus 2014年

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

这将打印完整的文件名(包括路径),然后打印文件的内容。它也非常灵活,因为您可以将-name“ expr”用于find命令,并在文件上运行任意数量的命令。


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

查找,显示文件的路径并显示每个文件。


2

这是一个非常简单的方法。您说过要猫,这意味着您要查看整个文件。但是您还需要打印文件名。

尝试这个

head -n99999999 * 要么 head -n99999999 file1.txt file2.txt file3.txt

希望能有所帮助


4
一种更干净的语法是head -n -0 file.txt file2.txt file3.txt。适用head于GNU 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,如果你想跟踪正在被写入一个文件,但没有真正什么样的任择议定书要求的范围之内是非常有用的。
2015年

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每次迭代将echo所述$file串那么它的管道输送到一个cut其中I使用的命令.为字段分隔符打破fileX.txt成两个部分,并打印出FIELD1(FIELD2是TXT)的其余部分应该明确
的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

首先,我创建了每个文件:为每个文件[123] .txt回显'信息'> file1.txt。

然后我打印每个文件以确保信息正确:tail file?.txt

然后我这样做了:尾文件?.txt >> Mainfile.txt。这创建了Mainfile.txt,以将每个文件中的信息存储到主文件中。

猫Mainfile.txt确认还可以。

==> file1.txt <== bluemoongoodbeer

==> file2.txt <== awesomepossum

==> file3.txt <== hownowbrowncow

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.