Saya memiliki folder dengan sekitar 20 ribu file. File-file tersebut dinamai sesuai dengan pola xy_{\d1,5}_{\d4}\.abc
, misalnya xy_12345_1234.abc
. Saya ingin mengompresi 10K pertama dari mereka menggunakan perintah ini:
ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz
namun file yang dihasilkan hanya memiliki sekitar 2K file di dalamnya.
ls | sort -n -k1.4,1.9 | head -n10000 | wc -l
namun mengembalikan 10.000, seperti yang diharapkan.
Sepertinya saya salah paham tentang sesuatu yang mendasar di sini ...
Saya menggunakan zsh 5.0.2 di Linux Mint 17.1, GNU tar 1.27.1
EDIT:
forking seperti yang disarankan oleh @Archemar terdengar sangat masuk akal, dengan garpu terbaru menimpa file yang dihasilkan - file tersebut berisi 'ekor' file - 7773 hingga 9999 .
hasil dari xargs --show-limit
:
Your environment variables take up 3973 bytes
POSIX upper limit on argument length (this system): 2091131
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2087158
Size of command buffer we are actually using: 131072
mengganti -c
dengan -r
atau -u
tidak berfungsi dalam kasus saya. Pesan kesalahan tadinyatar: Cannot update compressed archives
menggunakan keduanya -r
dan -u
tidak valid dan gagal dengantar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option
mengganti -c
dengan -a
tampaknya tidak valid juga dan gagal dengan yang sama tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
meskipun saya tidak mengenali masalah ini azf
dan Acdtrux
tampak terpisah bagi saya.
EDIT 2:
-T sepertinya cara yang baik, saya juga menemukan contoh di sini .
Namun ketika saya coba
ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T -
saya mendapat
tar: option requires an argument -- 'T'
baik, mungkin nama file tidak mencapai tar? Tapi sepertinya mereka, lakukan karena ketika aku mengeksekusinya
ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T -
saya mendapat
tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab
Cannot stat: File name too long
Jadi mengapa tar tidak melihat nama file?
ls
find
, yang memiliki-print0
opsi untuk menggunakan byte nol sebagai pembatas, bukan baris baru.sort
dapat mengatasinya dengan-z
bendera.head
, sayangnya tidak menangani mengerti pembatas byte nol, tetapi jawaban ini memiliki solusi menggunakantr
untuk swap\n
dan\0
sebelum dan sesudahhead
.tar
harus--null -T -
membaca nama file yang dibatasi nol daristdin
.Jawaban:
Anda telah mencapai batas xargs?
coba:
.tgz
file dummytar czf xy_0_10000.tar.gz /hello/world
-czf
dengan-Azf
ketika xarg mencapai batasnya, ia akan melakukan perintah fork, jadi perintah yang Anda jalankan tadi adalah
karena setiap tar melewati yang sebelumnya, Anda hanya dapat
tar c
menjalankan terakhir .Edit:
1)
menurutmenambahkanman tar
pada unbuntu,-a
dan -r tampaknyasetaradilakukan oleh (baik)-A, --catenate, --concatenate
2)
zip
(tidakgzip
) dapat digunakan untuk menambahkan file, mungkin opsi gzip akan melakukan trik. (gunakan| xargs zip -qr xy_0_0000.zip
, ini akan menghasilkan file zip, bukan .tar.gz)3) untuk menggunakan solusi @ rsanchez
Sangat penting untuk menambahkan opsi tar dengan cara yang tepat, cobalah
where -
-T -
mean use option-T
dan gunakan-
sebagai argumen untuk-T
(Anda bisa menghasilkan daftar file/tmp/foo.lst
, lalu gunakan-T /tmp/foo.lst
)sumber
a (add)
untuk menambahkan file ke file tar. Kemudian, Anda dapat membuka tar dan menghapus folder (menggunakan 7zip atau sesuatu)touch xy_0_10000.tar.gz && { _the full command here_ ; }
.gz
file yang tidak valid .-r
tambahan tetapi-a
kompres otomatis yang tidak setara. Dan-rz
tidak berfungsi:zip
dapat menambah arsip yang ada karena direktori tidak dikompresi, tetapitar
dengan kompresi kompres metatdata bersama dengan data. Anda dapat secara terpisahtar -r
menjadi arsip yang tidak dikompresi dan kemudian gzip hasilnya. Atau ...Tidak perlu
xargs
. Jika Anda langsung memberikantar
yang-T -
pilihan itu akan membaca nama file dari input standar.Contohnya:
sumber
...| tar Tczf xy_...
,...| tar Tcz -f xy_...
...| tar -czf xy_... -T
dan beberapa permutasi lainnya, tetapi saya hanya mendapatkantar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
,tar: -f: Cannot stat: No such file or directory
jika menggunakan-f
secara terpisah dari opsi lain dantar: option requires an argument -- 'T'
. Bisakah Anda menambahkan contoh penggunaan?-T -
di akhirtar
daftar opsi tidak berfungsi, tetapi contoh Anda berhasil. Sayangnya, pertanyaan saya sebenarnya memiliki dua bagian - sumber kesalahan dan kemungkinan perbaikan. Sementara Anda menyetujui yang terakhir, Archemar unggul di mantan dan hampir memiliki yang terakhir benar. Saya tidak yakin jawaban mana yang Anda terima karena keduanya jelas membantu.Saya ingin melengkapi dua jawaban lain dengan solusi zsh , yang tidak mem-parsing ls , maupun membutuhkan xargs . Namun, saya tidak yakin sekarang, apakah itu juga menderita dari batasan panjang baris perintah.
Tentukan fungsi yang menghasilkan kunci penyortiran yang Anda inginkan dengan memodifikasi
$REPLY
.Ini setara dengan Anda
sort -n -k1.4,1.9
Buat array
$files
dengan nama file yang diurutkan dengan fungsi di atas:Ini setara dengan
ls | sort -n -k1.4,1.9
Kembalikan 10.000 file pertama dengan
Ini setara dengan
ls | sort -n -k1.4,1.9 | head -n10000
Jadi, semua ini harus melakukan trik:
sumber