Mengapa ini tidak berhasil? "Ls * .txt | xargs cat> all.txt ”(semua file menjadi dokumen txt tunggal)

18

Mengapa ini tidak berhasil?

ls *.txt | xargs cat > all.txt

(Saya ingin menggabungkan konten semua file teks menjadi file 'all.txt' tunggal.) temukan dengan -exec juga harus berfungsi, tetapi saya benar-benar ingin memahami sintaks xargs.

Terima kasih

ajo
sumber

Jawaban:

25

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

mungkin bekerja sedikit lebih baik, karena itu akan ditambahkan ke all.txt daripada membuatnya lagi setelah setiap file.

Ngomong-ngomong, cat *.txt >all.txt juga akan bekerja. :-)

Janne Pikkarainen
sumber
6
Cat * .txt & gt; all.txt secara alami lebih baik. Terima kasih
ajo
Namun, ... | xargs cat & gt; & gt; all.txt atau & gt; all.txt selalu mengembalikan kesalahan dengan xargs: kutipan tunggal tak tertandingi ... Apakah karena xargs mengambil semuanya setelah itu sebagai perintah?
ajo
1
Apakah Anda memiliki nama file dengan spasi? Jika ya, gunakan sesuatu seperti "find / your / path -iname '* .txt' -print0 | xargs -0 cat & gt; & gt; all.txt"
Janne Pikkarainen
1
tidak, saya mengganti semua ruang nama file dengan . Tetapi memikirkannya, beberapa nama file cenderung menyertakan tanda kutip tunggal seperti pada listing_O'Connor .txt, ini mungkin masalahnya!
ajo
Ya, itu masalahnya. :) Cara termudah dan paling jernih adalah menggunakan find dengan -print0 dikombinasikan dengan xargs -0 - maka seluruh rantai akan menggunakan karakter NULL sebagai pemisah dan spasi putih dan karakter khusus akan dijaga secara otomatis.
Janne Pikkarainen
3

Jika beberapa nama file Anda berisi ', "atau spasi xargs akan gagal karena masalah pemisah

Secara umum tidak pernah berjalan xargs tanpa -0 karena akan kembali dan menggigit Anda suatu hari.

Sebaiknya gunakan GNU Parallel:

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

atau jika Anda lebih suka:

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

Pelajari lebih lanjut tentang GNU Parallel http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
sumber
1

all.txt adalah file di direktori yang sama, jadi kucing jadi bingung ketika ingin menulis dari file yang sama ke file yang sama.

Di samping itu:

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

Ini akan membaca dari file teks dalam direktori Anda saat ini ke all.txt dalam subdirektori (tidak termasuk dengan *.txt ).

Jeremy Smyth
sumber
Masih kesalahan berikut: xargs: kutipan tunggal tidak cocok; secara default, harga khusus untuk xargs kecuali Anda menggunakan opsi -0
ajo
1
Apakah Anda memiliki file .txt dengan satu kutipan di namanya?
Jeremy Smyth
0

Anda juga bisa menemukan batasan panjang baris perintah. Bagian dari alasan untuk menggunakan xargs adalah bahwa ia membagi input menjadi potongan-potongan berukuran garis perintah yang aman. Jadi, bayangkan sebuah situasi di mana Anda memiliki ratusan ribu file .txt di direktori. ls *.txt akan gagal. Anda perlu melakukannya

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

.txt$ dalam hal ini adalah ekspresi reguler yang cocok dengan semua yang berakhiran .txt (jadi tidak persis seperti itu *.txt, karena jika Anda memiliki file bernama atxt, kemudian *.txt tidak akan cocok dengan itu, tetapi ungkapan reguler akan.)

Penggunaan lintasan lain karena, seperti yang ditunjukkan oleh jawaban lain, all.txt dicocokkan dengan pola *.txt jadi akan ada konflik antara input dan output.

Perhatikan bahwa jika Anda memiliki file dengan ' dalam nama mereka (dan ini mungkin menjadi penyebab unmatched single quote kesalahan), Anda ingin melakukannya

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

Opsi --null memberi tahu grep untuk menggunakan output yang dipisahkan oleh a \0 (alias null) karakter alih-alih baris baru default, dan -0 opsi untuk `xargs memberitahu dia untuk mengharapkan inputnya dalam format yang sama. Ini akan berfungsi bahkan jika Anda memiliki nama file dengan baris baru di dalamnya.

Brian Minton
sumber