Ghép nhiều tệp nhưng bao gồm tên tệp làm tiêu đề phần


352

Tôi muốn ghép một số tệp văn bản thành một tệp lớn trong thiết bị đầu cuối. Tôi biết tôi có thể làm điều này bằng cách sử dụng lệnh mèo. Tuy nhiên, tôi muốn tên tệp của mỗi tệp đứng trước "kết xuất dữ liệu" cho tệp đó. Bất cứ ai biết làm thế nào để làm điều này?

những gì tôi hiện đang có:

file1.txt = bluemoongoodbeer

file2.txt = awesomepossum

file3.txt = hownowbrowncow

cat file1.txt file2.txt file3.txt

sản phẩm chất lượng:

file1

bluemoongoodbeer

file2

awesomepossum

file3

hownowbrowncow

Tôi thực sự đang sử dụng uuencode & uudecode để làm một cái gì đó tương tự, tôi không cần tập tin có thể đọc được ở giữa, chỉ cần kết quả và chuyển chúng sang một lệnh khác một lần nữa

Câu trả lời:


531

Đã tìm kiếm điều tương tự, và tìm thấy điều này để gợi ý:

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

Đầu ra:

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

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

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

Nếu chỉ có một tệp duy nhất thì tiêu đề sẽ không được in. Nếu sử dụng GNU utils, bạn có thể sử dụng -vđể luôn in tiêu đề.


2
Điều này cũng hoạt động với đuôi GNU (một phần của GNU Coreutils).
ArjunShankar

7
-n +1Lựa chọn tuyệt vời ! Một thay thế : head -n-0 file1 file2 file3.
Ngọn lửa băng giá

2
Hoạt động tuyệt vời với cả đuôi BSD và đuôi GNU trên MacOS X. Bạn có thể bỏ không gian giữa -n+1, như trong -n+1.
vdm

4
tail -n +1 *chính xác là tôi đang tìm kiếm, cảm ơn!
kR105

1
hoạt động trên MacOsX 10.14.4sudo ulimit -n 1024; find -f . -name "*.rb" | xargs tail -n+1 > ./source_ruby.txt
kolas

186

Tôi đã sử dụng grep cho một cái gì đó tương tự:

grep "" *.txt

Nó không cung cấp cho bạn một 'tiêu đề', nhưng tiền tố mỗi dòng có tên tệp.


10
Ngắt đầu ra nếu *.txtmở rộng thành chỉ một tập tin. Về vấn đề này, tôi khuyên bạngrep '' /dev/null *.txt
antak

1
+1 để hiển thị cho tôi cách sử dụng mới cho grep. điều này đáp ứng hoàn hảo nhu cầu của tôi trong trường hợp của tôi, mỗi tệp chỉ chứa một dòng, do đó, nó mang lại cho tôi một đầu ra được định dạng gọn gàng, có thể dễ dàng phân tích
cú pháp

9
grepsẽ chỉ in các tiêu đề tệp nếu có nhiều hơn một tệp. Nếu bạn muốn đảm bảo in đường dẫn tệp luôn, hãy sử dụng -H. Nếu bạn không muốn các tiêu đề sử dụng -h. Cũng lưu ý rằng nó sẽ in (standard input)cho STDIN.
Jorge Bucaran

1
Bạn cũng có thể sử dụng ag(trình tìm kiếm bạc): theo mặc định, ag . *.txttiền tố mỗi tệp có tên của nó và mỗi dòng có số của nó.
anol

1
Lưu ý, chuyển -nđến grep cũng mang lại số dòng cho phép bạn viết các lint đơn giản với xác định chính xác có thể được chọn bởi, ví dụ, emacs.
DepressionDaniel

104

Điều này cũng nên làm như vậy:

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

Có nghĩa:

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

Bạn cũng có thể kết hợp tìm kiếm các toán tử boolean máng như -andhoặc -or. find -lscũng tốt


1
Bạn có thể giải thích thêm những gì lệnh này không? Chính xác là những gì tôi cần
AAlvz

4
Đây là lệnh tìm tiêu chuẩn của linux. Nó tìm kiếm tất cả các tệp trong thư mục hiện tại, in tên của chúng, sau đó cho từng tệp, gửi tệp. Bỏ qua -printsẽ không in tên tệp trước cat.
Maxim_united

17
Bạn cũng có thể sử dụng -printfđể tùy chỉnh đầu ra. Ví dụ: find *.conf -type f -printf '\n==> %p <==\n' -exec cat {} \;để khớp với đầu ra củatail -n +1 *
Maxim_united

1
-printf không hoạt động trên mac, trừ khi bạn muốn brew install findutilsvà sau đó sử dụng gfindthay vì find.
Matt Fletcher

1
Nếu bạn muốn màu sắc, bạn có thể sử dụng thực tế đó findcho phép nhiều -execs:find -name '*.conf' -exec printf '\n\e[33;1m%s\e[0m\n' {} \; -exec cat {} \;
banbh

24

Cái này cần phải dùng mẹo:

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

hoặc để làm điều này cho tất cả các tệp văn bản đệ quy:

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

1
đã không làm việc. Tôi vừa viết một số mã awk thực sự xấu xí: với tôi trong $ listoffiles do awk '{in FILENAME, $ 0, $ 1, $ 2, $ 3, $ 4, $ 5, $ 6, $ 7, $ 8, $ 9, $ 10, $ 11}' $ i >> concat.txt đã hoàn thành
Nick

2
... quan tâm đến công phu? Điều đó đơn giản như mã bash.
Chris Eberle

@Nick: dòng awk của bạn thậm chí không hoạt động, vì đó $0là toàn bộ dòng, vì vậy bạn thực sự có các cột lặp lại ở đó ...
Chris Eberle

@Nick: Giải pháp tiện lợi khác :)
Chris Eberle

@Chris: đúng, nhưng nó xấu hơn nhiều so với tôi mong muốn. Có lẽ mã của bạn không hoạt động với tôi vì tôi đang sử dụng >> để bắt lỗi thiết bị xuất chuẩn?
Nick

17

Tôi đã có một loạt các tệp kết thúc bằng stats.txt mà tôi muốn ghép nối với tên tệp.

Tôi đã làm như sau và khi có nhiều hơn một tệp, lệnh "more" bao gồm tên tệp làm tiêu đề.

more *stats.txt > stats.txt

hoặc cho một trường hợp chung

more FILES_TO_CONCAT > OUTPUT_FILE

5
more <FILES> | cat
Acumenus

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

Điều này sẽ in tên tệp đầy đủ (bao gồm cả đường dẫn), sau đó là nội dung của tệp. Nó cũng rất linh hoạt, vì bạn có thể sử dụng -name "expr" cho lệnh find và chạy bao nhiêu lệnh tùy thích trên các tệp.


1
Nó cũng khá đơn giản để kết hợp với grep. Để sử dụng với bash:find . -type f -print | grep PATTERN | xargs -n 1 -I {} -i bash -c 'echo ==== {} ====; cat {}; echo'
dojuba

5

Tôi thích tùy chọn này

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

Đầu ra trông như thế này:

./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

Đây là cách tôi thường xử lý định dạng như thế:

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

Tôi thường đưa con mèo vào một grep để biết thông tin cụ thể.


3
Hãy cẩn thận ở đây. for i in *sẽ không bao gồm các thư mục con.
Acumenus


3

bạn có thể sử dụng lệnh đơn giản này thay vì sử dụng vòng lặp for

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

3

Nếu bạn thích màu sắc, hãy thử điều này:

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

hoặc là:

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

hoặc: (đã cài đặt gói 'đa nhiệm')

multitail *

1
Vì lợi ích của màu sắc làm nổi bật tên tệp:find . -type f -name "*.txt" | xargs -I {} bash -c "echo $'\e[33;1m'{}$'\e[0m';cat {}"
MediaVince

3

Nếu tất cả các tệp có cùng tên hoặc có thể được khớp bởi find, bạn có thể làm (ví dụ):

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

để tìm, hiển thị đường dẫn và cat mỗi tệp.


2

Đây là một cách thực sự đơn giản. Bạn nói rằng bạn muốn mèo, ngụ ý rằng bạn muốn xem toàn bộ tập tin. Nhưng bạn cũng cần tên tệp được in.

Thử cái này

head -n99999999 * hoặc là head -n99999999 file1.txt file2.txt file3.txt

Mong rằng sẽ giúp


4
một cú pháp sạch hơn sẽ là head -n -0 file.txt file2.txt file3.txt. Hoạt động headtrong
lõi core

1

Phương pháp này sẽ in tên tệp và sau đó nội dung tệp:

tail -f file1.txt file2.txt

Đầu ra:

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

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

3
Điều -fnày rất hữu ích nếu bạn muốn theo dõi một tệp đang được ghi, nhưng không thực sự nằm trong phạm vi của những gì OP yêu cầu.
tripleee

1

Nếu bạn muốn thay thế những thứ xấu xí đó ==> <== bằng thứ khác

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

giải trình:

tail -n +1 *.txt - xuất tất cả các tệp trong thư mục có tiêu đề

sed -e 's/==>/\n###/g' -e 's/<==/###/g'- thay thế ==>bằng dòng mới + ###<==chỉ với ###

>> "files.txt" - xuất tất cả ra một tệp



0

Nếu bạn muốn kết quả ở cùng định dạng với đầu ra mong muốn của mình, bạn có thể thử:

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

Kết quả:

file1
bluemoongoodbeer
file2
awesomepossum
file3
hownowbrowncow

Bạn có thể đặt echo -etrước và sau khi cắt để bạn cũng có khoảng cách giữa các dòng:

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

Kết quả:

file1

bluemoongoodbeer

file2

awesomepossum

file3

hownowbrowncow

Giải thích: forvòng lặp đi qua danh sách lslệnh kết quả. $ ls file{1..3}.txtKết quả: file1.txt file2.txt file3.txtmỗi lần lặp sẽ echocác $filechuỗi sau đó nó được đường ống vào một cutlệnh mà tôi sử dụng .như một tách lĩnh vực mà phá vỡ fileX.txt thành hai mảnh và in ra các field1 (field2 là txt) Phần còn lại phải rõ ràng
Fekete Sumer

0
  • AIX 7.1 ksh

... tham gia vào những người đã đề cập đến công việc đầu cho một số người trong chúng ta:

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

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

==> file3.txt <==
zzz
$

Nhu cầu của tôi là đọc dòng đầu tiên; như đã lưu ý, nếu bạn muốn có hơn 10 dòng, bạn sẽ phải thêm tùy chọn (đầu -9999, v.v.).

Xin lỗi vì đã đăng một bình luận phái sinh; Tôi không có đủ tín dụng đường phố để bình luận / thêm vào nhận xét của ai đó.


-1

Để giải quyết công việc này, tôi thường sử dụng lệnh sau:

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

Đây là một cách rất thuận tiện để ghép các tệp nếu số lượng tệp khá lớn.


1
Nhưng điều này không trả lời câu hỏi của OP.
kaugeour

-3

Đầu tiên tôi tạo từng tệp: echo 'information'> file1.txt cho mỗi tệp [123] .txt.

Sau đó, tôi đã in từng tệp để đảm bảo thông tin là chính xác: tệp đuôi? .Txt

Sau đó, tôi đã làm điều này: tập tin đuôi? .Txt >> Mainfile.txt. Điều này đã tạo Mainfile.txt để lưu trữ thông tin trong mỗi tệp vào một tệp chính.

mèo Mainfile.txt xác nhận nó vẫn ổn.

==> file1.txt <== bluemoongoodbeer

==> file2.txt <== awesomepossum

==> file3.txt <== hownowbrowncow

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.