Tại sao cai nay không hoạt động? Tiếng ls * .txt | xargs cat> all.txt '(tất cả các tệp vào một tài liệu txt)


20

Tại sao cai nay không hoạt động?

ls *.txt | xargs cat > all.txt

(Tôi muốn nối các nội dung của tất cả các tệp văn bản vào một tệp 'all.txt'.) Find with -exec cũng sẽ hoạt động, nhưng tôi thực sự muốn hiểu cú pháp xargs.

Cảm ơn


1
Mặc dù không sử dụng lscho việc này . Nếu bạn thực sự không thể sử dụng cat *.txt >all.txtthì hãy thử printf '%s\0' *.txt | xargs -r0 cat >allvà sau đó mv all all.txtđể tránh có tệp tham chiếu chính nó.
tripleee

Câu trả lời:


27

ls *.txt | xargs cat >> all.txt

có thể hoạt động tốt hơn một chút, vì nó sẽ nối vào all.txt thay vì tạo lại sau mỗi tệp.

Nhân tiện, cat *.txt >all.txtcũng sẽ làm việc. :-)


6
Con mèo * .txt> all.txt tự nhiên tốt hơn. Cảm ơn
ajo

1
Tuy nhiên, ... | xargs cat >> all.txt hoặc> all.txt luôn trả về lỗi với xargs: trích dẫn đơn chưa từng có ... Có phải vì xargs lấy mọi thứ sau nó làm lệnh?
ajo

1
Bạn có tên tập tin với không gian? Nếu vậy, sau đó sử dụng cái gì đó như "find / your / path -iname '* .txt' -print0 | xargs -0 cat >> all.txt" thay vào đó
Janne Pikkarainen

1
không, tôi đã thay thế tất cả các không gian tên tệp bằng . Nhưng nghĩ về nó, một số tên tệp có thể bao gồm các trích dẫn đơn lẻ như trong list_O'Connor .txt, đây có thể là vấn đề!
ajo

Vâng, đó là vấn đề sau đó. :) Cách dễ nhất và hợp lý nhất là sử dụng find với -print0 kết hợp với xargs -0 - sau đó toàn bộ chuỗi sẽ sử dụng ký tự NULL làm dấu tách và khoảng trắng và các ký tự đặc biệt sẽ được xử lý tự động.
Janne Pikkarainen

3

Nếu một số tên tệp của bạn chứa ', "hoặc dấu cách xargssẽ không thành công do sự cố dấu phân cách

Nói chung không bao giờ chạy xargsmà không -0 vì nó sẽ quay lại và cắn bạn một ngày nào đó.

Thay vào đó, hãy xem xét sử dụng GNU Parallel:

ls *.txt | parallel cat > tmp/all.txt

hoặc nếu bạn thích:

ls *.txt | parallel cat >> tmp/all.txt

Tìm hiểu thêm về Song song GNU http://www.youtube.com/watch?v=OpaiGYxkSuQ


1

all.txt là một tệp trong cùng một thư mục, vì vậy mèo bị lẫn lộn khi nó muốn ghi từ cùng một tệp vào cùng một tệp.

Mặt khác:

ls *.txt | xargs cat > tmp/all.txt

Điều này sẽ đọc từ các tệp văn bản trong thư mục hiện tại của bạn vào all.txt trong thư mục con (không bao gồm *.txt).


Vẫn còn lỗi sau: xargs: trích dẫn đơn chưa từng có; theo mặc định, trích dẫn là đặc biệt đối với xargs trừ khi bạn sử dụng tùy chọn -0
ajo

1
Bạn có tệp .txt với một tên đơn trong tên của nó không?
Jeremy Smyth

0

Bạn cũng có thể đi qua một giới hạn độ dài dòng lệnh. Một phần lý do của việc sử dụng xargslà nó phân tách đầu vào thành các khối có kích thước dòng lệnh an toàn. Vì vậy, hãy tưởng tượng một tình huống trong đó bạn có hàng trăm ngàn tệp .txt trong thư mục. ls *.txtsẽ thất bại. Bạn sẽ cần phải làm

ls | grep .txt$ |xargs cat > /some/other/path/all.txt

.txt$trong trường hợp này là một biểu thức chính quy khớp với mọi thứ kết thúc bằng .txt (vì vậy nó không chính xác như thế *.txt, vì nếu bạn có một tệp được gọi atxt, thì *.txtsẽ không khớp với nó, nhưng biểu thức chính quy sẽ.)

Việc sử dụng một đường dẫn khác là vì, như các câu trả lời khác đã chỉ ra, all.txt được khớp với mẫu *.txtnên sẽ có xung đột giữa đầu vào và đầu ra.

Lưu ý rằng nếu bạn có bất kỳ tệp nào có 'tên của họ (và đây có thể là nguyên nhân gây ra unmatched single quotelỗi), bạn sẽ muốn làm

ls | grep --null .txt$ | xargs -0 cat > /some/other/path/all.txt

Tùy chọn --null bảo grep sử dụng đầu ra được phân tách bằng \0ký tự (còn gọi là null) thay vì dòng mới mặc định và -0tùy chọn `xargs bảo nó mong đợi đầu vào của nó ở cùng định dạng. Điều này sẽ hoạt động ngay cả khi bạn có tên tệp với dòng mới trong đó.

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.