'खोज' के साथ 'टार' कमांड को कैसे संयोजित करें


31

खोज आदेश यह आउटपुट देता है:

[रूट @ लोकलहोस्ट /] # वर / लॉग / -नाम एनाकोंडा खोजें। *
var / लॉग / anaconda.log
var / लॉग / anaconda.xlog
var / लॉग / anaconda.yum.log
var / लॉग / anaconda.syslog
var / लॉग / anaconda.program.log
var / लॉग / anaconda.storage.log

टार के साथ संयोजन के बाद यह इस उत्पादन को दिखा रहा है:

[रूट @ लोकलहोस्ट /] # वर / लॉग / -नाम एनाकोंडा खोजें। * -exec tar -cvf file.tar {} \;
var / लॉग / anaconda.log
var / लॉग / anaconda.xlog
var / लॉग / anaconda.yum.log
var / लॉग / anaconda.syslog
var / लॉग / anaconda.program.log
var / लॉग / anaconda.storage.log

लेकिन टार फाइल को सूचीबद्ध करते समय यह केवल एक ही फाइल दिखा रहा है

[root @ localhost /] # tar -tvf file.tar
-rw ------- रूट / रूट 208454 2012-02-27 12:01 var / log / anaconda.storage.log

मैं यहां क्या गलत कर रहा हूं?

Xargs के साथ मुझे यह आउटपुट मिल रहा है:

[root @ localhost /] # खोज var / log / -iname anaconda। * xargs tar -cvf file1.tar

दूसरा सवाल

Var के सामने / टाइप करते समय , इसका अर्थ find /var/logयह है कि यह मेसैज टार दे रहा है: प्रमुख नामों से `` को हटा रहा है

[रूट @ लोकलहोस्ट /] # खोजें / var / log / -iname anaconda। * -exec tar -cvf file.tar {} \;
टार: प्रमुख नामों से प्रमुख `/ 'हटाना
/var/log/anaconda.log
टार: प्रमुख नामों से प्रमुख `/ 'हटाना
/var/log/anaconda.xlog
टार: प्रमुख नामों से प्रमुख `/ 'हटाना
/var/log/anaconda.yum.log
टार: प्रमुख नामों से प्रमुख `/ 'हटाना
/var/log/anaconda.syslog
टार: प्रमुख नामों से प्रमुख `/ 'हटाना
/var/log/anaconda.program.log
टार: प्रमुख नामों से प्रमुख `/ 'हटाना
/var/log/anaconda.storage.log

सरल रूप में निम्नलिखित दो में क्या अंतर है?

find var/log तथा find /var/log


यह सेमी + ऑफ विषय है, लेकिन findकमांड के साथ आगे बढ़ते हुए , आपको खोज शब्द को उद्धृत करना चाहिए। यह कभी-कभी नहीं बल्कि हमेशा काम करता है।
nerdwaller

1
यदि आप {} +इसके बजाय {} \;इसका उपयोग करते हैं, तो एक तर्क में पता लगाने के समूह के परिणाम होंगे
जेसन एस

जवाबों:


39

नोट: कुछ अधिक कुशल समाधान के लिए @ इयान का उत्तर देखें ।

ध्यान दें कि यह खोजने वाली हर एक फ़ाइल के लिए कार्रवाई findको कॉल करेगा ।-exec

यदि आप tar -cvf file.tar {}हर एक फ़ाइल findआउटपुट के लिए दौड़ते हैं , तो इसका मतलब है कि आप file.tarहर बार ओवरराइट करेंगे , जो बताता है कि आप केवल एक संग्रह के साथ समाप्त क्यों होते हैं जिसमें केवल शामिल होता है anaconda.storage.log- यह अंतिम फ़ाइल findआउटपुट है।

अब, आप वास्तव में फ़ाइलों को हर बार बनाने के बजाय संग्रह में जोड़ना चाहते हैं (यह वही है जो -cविकल्प करता है)। तो, निम्नलिखित का उपयोग करें:

find var/log/ -iname "anaconda.*" -exec tar -rvf file.tar {} \;

-rविकल्प के बजाय यह हर बार पुनः बनाने का संग्रह करने के लिए जोड़ देता है।

नोट:-iname anaconda.* साथ बदलें -iname "anaconda.*"। तारांकन एक वाइल्डकार्ड है और इसे देखने से पहले अपने शेल द्वारा विस्तारित किया जा सकता findहै। इस विस्तार को रोकने के लिए, तर्क को दोहरे उद्धरण चिह्नों में लपेटें।


tarप्रमुख को हटाने के लिए /: संग्रह में केवल सापेक्ष फ़ाइल नाम होना चाहिए । यदि आपने एक अग्रणी के साथ फ़ाइलें जोड़ी हैं /, तो उन्हें पूर्ण फ़ाइल नामों के रूप में संग्रहीत किया जाएगा /var/…, उदाहरण के लिए आपके कंप्यूटर पर शाब्दिक अर्थ ।

IIRC यह केवल tarGNU के अलावा अन्य कार्यान्वयन के लिए एक एहतियात है , और यह इस तरह से सुरक्षित है क्योंकि /var/…जब आप संग्रह को निकालते हैं तो यह आपके वास्तविक डेटा को अधिलेखित नहीं करेगा यदि इसमें रिश्तेदार फ़ाइल नाम शामिल हैं।


6
लेकिन ध्यान दें कि अगर आपने tarइस तरह से एक वास्तविक टेप आर्काइव करने की कोशिश की है , उस समय एक फाइल को जोड़कर, टेप को रिवाइंड करते हुए, तो अंत तक पहुंचने के लिए हर बार पूरी बात का पुनर्मूल्यांकन करें, पूरी बात हास्यास्पद रूप से धीमी हो जाएगी। यदि आप डिस्क पर टार फाइल लिख रहे हैं तो आपका समाधान केवल उपयुक्त है।
निकोल हैमिल्टन

2
यह सच है, लेकिन मुझे लगता है कि हम सुरक्षित रूप से इस स्थिति की अवहेलना कर सकते हैं;)
15

@slhck * एक वाइल्डकार्ड है जो सभी संभावनाओं को सही से मेल खाना चाहिए? लेकिन यहाँ find /var/log/ -iname anaconda*कुछ भी नहीं find /var/log/ -iname anaconda.*दे रहा है और आउटपुट दे रहा है, क्यों?
अधिकतम

जब एक वाइल्डकार्ड का उपभोग किया जाता है, तो यह findअब तक नहीं देखा जाएगा । इसलिए यदि आपके पास है anaconda*, और आपके वर्तमान फ़ोल्डर में कुछ नाम है, उदाहरण के लिए, anaconda5(इस वाइल्डकार्ड से मेल खाते हुए), वाइल्डकार्ड का विस्तार किया findजाएगा , और -iname anaconda5इसके बजाय देखेंगे -iname anaconda*। पहला काम क्यों नहीं करता है और दूसरा यह निर्भर करता है कि आपकी वर्तमान निर्देशिका में कौन सी फाइलें हैं। @ मोम
slhck

2
आप {} +इसके बजाय का उपयोग कर सकते हैं {} \;यह एक तर्क में खोजने के परिणामों को समूहित करेगा
जेसन एस

41

आप कुछ का उपयोग कर सकते हैं जैसे:

find var/log -iname 'anaconda.*' -print0 | tar -cvf somefile.tar --null -T -

-print0और -Tएक साथ काम रिक्त स्थान नई-पंक्तियों, आदि के साथ फ़ाइल नाम अनुमति देने के लिए अंतिम -टार बताता stdin से इनपुट फ़ाइल नामों को पढ़ने के लिए।

ध्यान दें कि इस उत्तर के-print0 अनुसार, आपके कथन के अंत में आना चाहिए । अन्यथा आपको शायद आपकी अपेक्षा से अधिक फाइलें मिलेंगी।


2
आपने -nameविकल्प को छोड़ दिया है, जिससे tarपूरी निर्देशिका में आपका समाधान हो जाएगा। यदि आप चाहते हैं, तो आप इसे अधिक आसानी से कर सकते हैं जैसे कि tar -cvf file.tar var/logबिना उपयोग किए find
निकोल हैमिल्टन

2
+1 सूची को ढेर करना tarएक अच्छा विचार है। यह निश्चित रूप से सबसे अच्छा समाधान है यदि आप उम्मीद करते हैं कि मार्ग में रिक्त स्थान हो सकते हैं। मैं इसे तकनीकी रूप से सर्वश्रेष्ठ भी बताऊंगा, क्योंकि यह विश्वसनीय और कुशल दोनों है। लेकिन इसके लिए दोनों के अतिरिक्त विशेष ज्ञान की आवश्यकता होती है findऔर tar। मैं कमांड प्रतिस्थापन को बहुत पसंद करता हूं केवल इसलिए कि यह एक अधिक सामान्य उपकरण है: जानें कि इसे एक बार कैसे उपयोग करना है, फिर हर जगह इसका उपयोग करें। (लेकिन मैं मानता हूं, मैं एक शेल के साथ विंडोज पर हूं जहां यह हमेशा काम करता है।) क्षमा याचना अगर मैं कठोर लग रहा था।
निकोल हैमिल्टन

2
आपको पहले से ही अपना +1 मिला है। खुश रहो। :) लॉन्ग कमांड लाइन हमेशा किसी भी OS पर प्रोसेस क्रिएशन i / f का बैन होता है। मुझे याद है कि 90 के दशक की शुरुआत में मार्क ल्युकोवस्की के साथ बहस करते हुए कि NT पर उनके 32K यूनिकोड वर्ण की सीमा बहुत छोटी थी और उनकी शिकायत थी कि मुझे पता नहीं था कि कर्नेल में हर जगह शॉर्ट्स की बजाय लंबाई को स्टोर करने में कितने अधिक बाइट्स लगते हैं। । आह। अधिक सामान्य केस सॉल्यूशन जब आर्ग लिस्ट बहुत लंबा है तो शेल में अधिक करना है (यदि संभव हो तो; मेरा यह है) या उपयोग करें xargs
निकोल हैमिल्टन

9
यदि आप खोज के -print0विकल्प का उपयोग करते हैं , तो आपको टार के --nullविकल्प की भी आवश्यकता है ।
18

2
और --no-unquoteसाथ ही जरूरत पड़ने पर निकलता है: बैकस्लैश वाले फ़ाइल नाम अन्यथा भ्रामक होंगे। (नहीं, यह एक काल्पनिक नहीं है - मैं वास्तव में किसी और के कोड से एक टार संग्रह बना रहा हूं, जिसमें नाम में बैकस्लैश के साथ एक फ़ाइल नाम है, यही कारण है कि मुझे पता चला है।)
hvd

12

इसे इस्तेमाल करे:

tar -cvf file.tar `find var/log/ -iname "anaconda.*"`

आप का उपयोग findकरने की कोशिश कर रहे थे -exec tar। लेकिन जिस तरह से यह -execविकल्प काम करता है, यह उस मिलान वाली फ़ाइल के लिए एक बार उस कमांड को चलाता है, जो हर बार उत्पन्न tarहोने वाली टार फ़ाइल को अधिलेखित करने का कारण बनता है। इसलिए आप केवल अंतिम एक के साथ समाप्त हो गए। इसके अलावा, आपको अपने द्वारा निर्दिष्ट पैटर्न के आसपास उद्धरण लगाने की आवश्यकता है findताकि शेल इसे पास करने से पहले इसका विस्तार न करें find

बैकस्टिक्स के साथ कमांड प्रतिस्थापन का उपयोग करना (या $(...)यदि आप पसंद करते हैं तो नोटेशन का उपयोग करके ), द्वारा निर्मित नामों की पूरी सूची findको तर्क के रूप में कमांड लाइन पर वापस चिपकाया जाता है tar, जिससे यह सब एक ही बार में लिखा जा सकता है।


2
यह खराब हो सकता है अगर उनके नाम, न्यूलाइन्स या ग्लोबिंग पात्रों में रिक्त स्थान के साथ आउटपुट फाइल मिल जाए। यह विफल होने के लिए बाध्य है - से स्टडआउट पाइपिंग findशायद ही कभी एक अच्छा विचार है। mywiki.wooledge.org/ParsingLs
slhck

3
@slhck, ढूंढने से स्टडआउट वास्तव में एक अच्छा विचार है, जैसा कि आप अपनी टिप्पणी में जुड़े पेज में बहुत स्पष्ट रूप से समझाया गया है :)। यह वास्तव में चीजों को करने का अनुशंसित तरीका है। आपको बस कुछ ट्रिक्स (जैसे ) read -rका उपयोग करना चाहिए जैसा -print0कि मैंने अपने जवाब में किया था।
टेराडॉन

4
@slhck यही कारण है कि यूनिक्स और लिनक्स में फ़ाइल और निर्देशिका नामों ने परंपरागत रूप से नामों में रिक्त स्थान से परहेज किया है। यह भी क्यों है, विंडोज पर, जहां रिक्त स्थान के नाम आम हैं, मैंने अपने स्वयं के हैमिल्टन सी शेल में एक अतिरिक्त कमांड प्रतिस्थापन संकेतन को जोड़ा जिसमें डबल बैकटिक्स का उपयोग किया गया है जो पूरी लाइनों (संभवतः रिक्त स्थान सहित) को एकल शब्दों के रूप में कमांड पर वापस चिपकाने के लिए उपयोग कर रहा है। लाइन। दुर्भाग्य से, यूनिक्स के किसी भी गोले में वह विशेषता नहीं है।
निकोल हैमिल्टन

1
उन्होंने पारंपरिक रूप से इसे टाला हो सकता है, लेकिन GUIs के माध्यम से उपयोगकर्ता स्थान में बनाई जा रही फ़ाइलों के साथ, आप अब रिक्त स्थान वाली फ़ाइलों की उपेक्षा नहीं कर सकते हैं और उन्हें द्वितीय श्रेणी के नागरिकों के रूप में मान सकते हैं (सिर्फ इसलिए कि यह यूनिक्स है)। यह अच्छा है कि आपने इसे अपने शेल में शामिल किया है, लेकिन यह विंडोज के लिए है, और यूनिक्स के गोले को विशेष रूप से उस सुविधा की आवश्यकता नहीं है यदि आप बस सही सिंटैक्स का उपयोग करते हैं और उचित सावधानी बरतते हैं। यही कारण है कि मैंने अपनी टिप्पणी पहली जगह में पोस्ट की है।
15

2
नहीं, लेकिन अन्य स्थानों पर यह बहुत अच्छी तरह से हो सकता है। यही कारण है कि रक्षात्मक रूप से प्रोग्राम करना एक अच्छा विचार है - सॉरी से बेहतर होना। इसके अलावा, इस सवाल को खोजने वाले आगंतुकों को वास्तव में एक ही समस्या नहीं हो सकती है और आश्चर्य है कि क्यों वे जो आदेश यहां प्राप्त करते हैं, वह इस मामले के लिए काम करने के लिए प्रकट हुए, लेकिन उनके लिए विफल रहे। मैं कमांड को ठीक करने के लिए इसे आपके ऊपर छोड़ दूंगा, मुझे लगा कि इसका उल्लेख करना महत्वपूर्ण है क्योंकि बहुत से लोग इस मुद्दे पर जल्दी या बाद में भाग लेते हैं।
16 अक्टूबर को

6

प्रश्न 1

आपकी कमांड विफल हो जाती है क्योंकि tarमिली हुई प्रत्येक फ़ाइल को ले रहा है और उन्हें संग्रहित कर रहा है file.tar। हर बार जब वह ऐसा करता है, तो वह पहले से बनाए गए ओवरराइट कर देगा file.tar

यदि आप चाहते हैं कि सभी फ़ाइलों के साथ एक संग्रह है, तो बस tarसीधे चलाएं , find(और हां, यह उनके नाम के रिक्त स्थान वाली फ़ाइलों के लिए काम करता है) की कोई आवश्यकता नहीं है :

tar -vcf file.tar /var/log/anaconda*   

प्रश्न 2

दो आदेश पूरी तरह से अलग हैं:

  • var / log खोजें एक निर्देशिका var/log खोजेगा, जिसे आपकी वर्तमान निर्देशिका का उपनिर्देशिका कहा जाता है , यह find ./var/log(नोटिस ./) के बराबर है ।

  • लगता है / var / लॉग नाम वाली निर्देशिका खोज करेंगे /var/log , जो रूट की उपनिर्देशिका है/

अग्रणी /संदेश से है tar, नहीं find। इसका अर्थ है कि यह /आपकी फ़ाइल नामों में से पहला हटा रहा है ताकि सापेक्ष में पूर्ण पथ बना सकें । इसका मतलब यह है कि जब आप संग्रह को अनटार्ट करते हैं, तब से फ़ाइल निकाली जाएगी ।/var/log/anaconda.error./var/log/anaconda.error


1

-execकाम करने के दो तरीके हो सकते हैं। एक तरीका कई बार कमांड चलाता है - प्रत्येक फ़ाइल के लिए एक बार; दूसरा तरीका एक बार कमांड चलाता है, जिसमें सभी फाइलों को मापदंडों की सूची के रूप में शामिल किया गया है।

  • -exec tar -cvf file.tar {} ';'tarहर बार संग्रह को अधिलेखित करते हुए, प्रत्येक फ़ाइल के लिए कमांड चलाता है ।
  • -exec tar -cvf file.tar {} '+'tarएक बार मिलने वाली सभी फाइलों का एक संग्रह बनाते हुए कमांड चलाता है।

1

मुझे लगता है कि प्रत्येक फ़ाइल के लिए -exec का उपयोग करके टार कंप्रेशन को बहुत धीमा कर सकते हैं, अगर आपके पास बहुत सारी फाइलें हैं। मैं कमांड का उपयोग करना पसंद करता हूं:

find . -iname "*.jpg" | cpio -ov -H tar -F jpgs.tar

जब तक यह विफल नहीं होता है/bin/cpio: xxx: Cannot open: Too many open files
SYN
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.