सभी फाइलें संपीड़ित क्यों नहीं हैं और समाधान कैसे सुधारें


8

मेरे पास लगभग 20K फ़ाइलों वाला एक फ़ोल्डर है। फाइलों का नाम पैटर्न के अनुसार रखा गया है xy_{\d1,5}_{\d4}\.abc, जैसे xy_12345_1234.abc। मैं इस कमांड का उपयोग करके उनमें से पहले 10K को संक्षिप्त करना चाहता था:

ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz

हालाँकि परिणामी फ़ाइल में केवल 2K फ़ाइलों के बारे में था।

ls | sort -n -k1.4,1.9 | head -n10000 | wc -l हालाँकि, उम्मीद के मुताबिक़ 10000 मिलते हैं।

ऐसा लगता है कि मैं यहाँ कुछ बुनियादी गलत समझ रहा हूँ ...

मैं लिनक्स मिंट 17.1, जीएनयू टार 1.27.1 पर zsh 5.0.2 का उपयोग कर रहा हूं

संपादित करें:

@Archemar द्वारा सुझाए गए के रूप में forking बहुत प्रशंसनीय लगता है, जिसके परिणामस्वरूप नवीनतम कांटा ओवररेटेड फ़ाइल - फ़ाइल में फ़ाइलों की 'पूंछ' - 7773 से 9999 तक होती है

का परिणाम 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

जगह -cके साथ -rया -uमेरे मामले में काम नहीं किया। त्रुटि संदेश थाtar: Cannot update compressed archives

दोनों का उपयोग कर -rऔर -uअमान्य है और साथ में विफल रहता हैtar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option

के -cसाथ की जगह के -aरूप में अच्छी तरह से अमान्य लगता है और उसी के साथ विफल रहता है, tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' optionsहालांकि मैं इस मुद्दे को नहीं पहचानता azfऔर Acdtruxमेरे लिए अप्रिय लगता हूं।

संपादित करें 2:

-एक अच्छा तरीका लगता है, मुझे यहां एक उदाहरण भी मिला है

हालाँकि जब मैं कोशिश करता हूँ

ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T - मुझे मिला tar: option requires an argument -- 'T'

ठीक है, शायद फ़ाइल नाम टार तक नहीं पहुँचते? लेकिन ऐसा लगता है कि वे करते हैं, क्योंकि जब मैं निष्पादित करता हूं

ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T - मुझे मिला tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab Cannot stat: File name too long

तो क्यों फिल्नामों को नहीं देख रहा है?


और यदि आप सी के बजाय टार कमांड में कोशिश करते हैं?
ओलिवियर दुलक


1
ओपी की फ़ाइल में मुश्किल नाम नहीं हैं।
आर्केमेयर

@ 8 बिट्टी - साथ ही मजबूत शेल स्क्रिप्ट के लिए एक सामान्य सलाह, हाँ। लेकिन आप नियमित वन-ऑफ ऑनलाइनर के साथ फ़ाइलों की सूची के साथ काम करने के बजाय क्या सुझाव देते हैं?
कोस्तजा

1
@kostja मैं उपयोग करूँगा find, जिसमें -print0एक न्यूलाइन के बजाय एक नल बाइट को सीमांकक के रूप में उपयोग करने का विकल्प है। ध्वज के sortसाथ संभाल सकता है -zhead, दुर्भाग्य से अशक्त बाइट सीमांकक को समझने संभाल नहीं है, लेकिन क्या यह उत्तर एक समाधान का उपयोग है trस्वैप करने के लिए \nऔर \0पहले और बाद में headtarहै --null -T -से अशक्त सीमांकित फ़ाइल नाम पढ़ने के लिए stdin
8bittree

जवाबों:


12

आप xargs सीमा मारा है?

xargs --show-limit

प्रयत्न :

  • डमी .tgzफ़ाइल बनाएँtar czf xy_0_10000.tar.gz /hello/world
  • -czfद्वारा प्रतिस्थापित करें-Azf

जब xarg ने अपनी सीमा पर प्रहार किया, तो यह कमांड को कांटा करेगा, इसलिए कमांड को आपने अल्टीमेटली चलाया था

  tar czf xy_0_10000.tar.gz file1 file2 .... file666
  tar czf xy_0_10000.tar.gz file667 file668 ... file1203
  tar czf xy_0_10000.tar.gz file1024 ... file2000

पिछले एक के ऊपर प्रत्येक टार के रूप में, आप केवल अंतिम tar cरन प्राप्त कर रहे थे।

संपादित करें:

1) unbuntu पर के अनुसार man tar, -aऔर -r लगता है समकक्ष (या तो) द्वारा किया जाता है -A, --catenate, --concatenate

2) zip(नहीं gzip) का उपयोग फ़ाइल को जोड़ने के लिए किया जा सकता है, शायद एक gzip विकल्प चाल करेगा। (उपयोग | xargs zip -qr xy_0_0000.zip, यह ज़िप फ़ाइल में परिणाम करेगा, एक .tar.gz हालांकि)

3) @ rsanchez के समाधान का उपयोग करने के लिए
उचित तरीके से टार के विकल्प को जोड़ना महत्वपूर्ण है, प्रयास करें

ls | sort -n -k1.4,1.9 | head -n10000 |tar -czf xy_0_10000.tar.gz -T -

जहां - -T -मतलब उपयोग विकल्प -Tऔर -तर्क के रूप में उपयोग करें -T(आप फ़ाइल की एक सूची उत्पन्न कर सकते हैं /tmp/foo.lst, फिर उपयोग करें -T /tmp/foo.lst)


क्या सी (= क्रिएट / ओवरराइट) के बजाय a (= add) उस सीमा के आसपास काम कर सकता है?
ओलिवियर दुलक

@OlivierDulac ( चेतावनी: यह एक शुद्ध अनुमान है ) यह शायद हल नहीं होगा क्योंकि टार खाली फाइलें नहीं बना सकते हैं। आप पहले एक खाली फ़ोल्डर को संपीड़ित कर सकते हैं और a (add)टार फ़ाइल में फ़ाइलों को जोड़ने के लिए उपयोग कर सकते हैं। फिर, आप टार खोल सकते हैं और फ़ोल्डर निकाल सकते हैं (7zip या कुछ का उपयोग करके)
Ismael Miguel

@ismaelmiguel: मुझे पूरा यकीन है कि यह खुशी से फाइल बनाएगा। यदि नहीं, तो बस:touch xy_0_10000.tar.gz && { _the full command here_ ; }
ओलिवियर दुलक

1
@OlivierDulac यह एक अमान्य .gzफ़ाइल होगी।
इस्माईल मिगुएल

मैं सभी manpages मैं manpages.ubuntu.com/manpages/vivid/en/man1/tar.1.html (15.04) से सटीक (12.04) तक वापस देख सकता हूं, जिसमें अपेंडमेंट है -rलेकिन -aऑटो-कंप्रेस जो समकक्ष नहीं है। और -rzकाम नहीं करता है: zipएक मौजूदा संग्रह में जोड़ सकता है क्योंकि निर्देशिका संकुचित नहीं है, लेकिन tarसंपीड़न के साथ डेटा के साथ मेटाडेटा को संपीड़ित करता है। आप tar -rएक असंपीड़ित संग्रह में टुकड़े टुकड़े कर सकते हैं और फिर परिणाम प्राप्त कर सकते हैं। या ...
dave_thompson_085

12

इसकी कोई आवश्यकता नहीं है xargs। यदि आप सीधे विकल्प देते हैं tarतो -T -यह मानक इनपुट से फाइलनाम पढ़ेगा

उदाहरण के लिए:

... | tar -T - -czf xy_0_10000.tar.gz

मुझे लगता है कि विकल्प गलत तरीके से उपयोग किया जा रहा है, इसे पाइप के साथ काम करने के लिए नहीं मिल सकता है। कोशिश की है ...| tar Tczf xy_..., ...| tar Tcz -f xy_... ...| tar -czf xy_... -T और कई अन्य क्रमपरिवर्तन, लेकिन केवल मिल रहा है tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options, tar: -f: Cannot stat: No such file or directoryअगर -fअन्य विकल्पों से अलग का उपयोग कर और tar: option requires an argument -- 'T'। क्या आप एक उपयोग उदाहरण जोड़ सकते हैं?
कोस्टजा

@kostja उदाहरण जोड़ा।
rsanchez

बहुत धन्यवाद, rsanchez निश्चित नहीं है कि विकल्प सूची -T -के अंत में मौजूद वेरिएंट tarने काम क्यों नहीं किया, लेकिन आपके उदाहरण ने किया। दुर्भाग्य से, मेरे प्रश्न में वास्तव में दो भाग थे - त्रुटि का स्रोत और एक संभावित सुधार। जब आपने उत्तरार्द्ध का उल्लेख किया, तो अर्चेमार ने पूर्व में उत्कृष्ट प्रदर्शन किया और लगभग उत्तरार्द्ध सही था। मुझे यकीन नहीं है कि आपके उत्तर में से कौन सा स्वीकार करने के लिए दोनों स्पष्ट रूप से सहायक थे।
कोस्तजा

1

मैं एक zsh समाधान के साथ दो अन्य उत्तरों को पूरक करना चाहता हूं , जो न तो पार्स एलएस , और न ही xargs की आवश्यकता है । हालाँकि, मुझे अभी यकीन नहीं है, अगर यह कमांड लाइन की लंबाई की सीमा से भी ग्रस्त है।

  1. एक फ़ंक्शन को परिभाषित करें जो संशोधित करके आपकी वांछित सॉर्टिंग कुंजी बनाता है $REPLY

    sortkey() { REPLY=${REPLY[4,9]} }

    यह आपके बराबर है sort -n -k1.4,1.9

  2. $filesउपरोक्त फ़ंक्शन के साथ हल किए गए फ़ाइल नाम के साथ एक सरणी बनाएं:

    files=(*(o+sortkey))

    इसके बराबर है ls | sort -n -k1.4,1.9

  3. पहले 10 000 फ़ाइलों के साथ लौटें

    ${files[0,9999]}

    इसके बराबर है ls | sort -n -k1.4,1.9 | head -n10000

तो, यह सब इस चाल में करना चाहिए:

sortkey() { REPLY=${REPLY[4,9]} }
files=(*(o+sortkey))
tar -czf xy_0_10000.tar.gz ${files[0,9999]}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.