एक्सगार्स / निष्पादन के लिए तर्क सूची बहुत लंबी है


2

मैं एक CentOS सर्वर पर काम कर रहा हूं और मुझे लाखों फ़ाइलों को एक साथ इधर-उधर ले जाना है। मैंने नीचे जैसे कुछ के कई अवतार लेने की कोशिश की है, लेकिन उनमें से सभी एक तर्क सूची के साथ बहुत लंबी त्रुटि के साथ विफल हो जाते हैं।

आदेश:

find ./ -iname out.* -type f -exec mv {} /home/user/trash
find ./paramsFile.* -exec cat > parameters.txt 

त्रुटि:

-bash: /usr/bin/find: Argument list too long
-bash: /bin/cat: Argument list too long

या

echo ./out.* | xargs -I '{}' mv /home/user/trash
(echo ./paramsFile.* | xargs cat) > parameters.txt  

त्रुटि:

xargs: argument line too long
xargs: argument line too long              

दूसरी आज्ञा भी कभी समाप्त नहीं हुई। मैंने ग्लोबिंग के बारे में कुछ बातें सुनी हैं, लेकिन मुझे यकीन नहीं है कि मैं इसे पूरी तरह से समझता हूं। किसी भी संकेत या सुझाव का स्वागत है!

जवाबों:


4

आपकी कई गलतियाँ हैं। आपको बचना चाहिए * ग्लोबिंग। आपको लगाना पड़ेगा {} उद्धरण के बीच (फ़ाइल नाम सुरक्षा के लिए), और आपको समाप्त करना होगा -exec साथ में \;

find ./ -iname out.\* -type f -exec mv "{}" /home/user/trash \;
find -name ./paramsFile.\* -exec cat "{}" >> parameters.txt \;

यहां समस्या यह है कि * आपकी निर्देशिका में सभी फ़ाइलों का मिलान कर रहा है, इस प्रकार आपको त्रुटि देता है। अगर find शेल ग्लोबिंग के बजाय फ़ाइलों का पता लगाता है, xargs अलग-अलग फ़ाइलनाम मिलते हैं जिनका उपयोग यह सही लंबाई की रेखाओं के निर्माण के लिए कर सकता है।


2
आपको नहीं लगाना है {} फ़ाइल नाम सुरक्षा के लिए उद्धरण के बीच! बिना उद्धरण के परिपूर्ण है जब तक कि आपका शेल इसके साथ अजीब सामान नहीं करता है।
gniourf_gniourf

1

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

find . -iname 'out.*' -type f -exec mv '{}' /home/user/trash \;
find . -name 'paramsFile.*' -print0 | xargs -0 cat >> parameters.txt

>> के कई आक्रमण सुनिश्चित करने के लिए है cat (यदि आपके पास वास्तव में बड़ी संख्या में फाइलें हैं) तो पिछली कॉल के परिणाम को ओवरराइट किए बिना, उसी फ़ाइल में आउटपुट। यह भी सुनिश्चित करें parameters.txt खाली शुरू होता है (या पहले इसे हटाएं)।


जवाब के लिए धन्यवाद! यह अभी भी लगता है और बिल्ली के लिए बहुत लंबा है।
ohblahitsme

ओह, मुझे लगता है कि मैंने वास्तव में ध्यान से नहीं पढ़ा है। मैंने दूसरे कॉल के साथ उत्तर को अपडेट किया। इसके अलावा, कुछ अच्छे बिंदुओं को लाने के लिए +1 से @ बर्नहार्ड, जिनके बारे में मैं भूल गया था।
jjlin

0

मेरे पास बहुत अच्छा (यानी, परीक्षण किया हुआ) उत्तर देने के लिए इस समय एक बॉक्स काम नहीं है, लेकिन मुझे लगता है कि यह एक अच्छा उपयोग है parallel

अगर मैं सही समझूं, आपकी आज्ञा

find ./ -iname out.* -type f -exec mv "{}" /home/user/trash

एक विशाल आदेश बना रहा है:

mv out.1 out.2 out.3 out.4 ... out.10100942 /home/user/trash

इसके बजाय, कुछ पसंद है

find ./ -iname out.* -type f | parallel mv "{}" /home/user/trash

लाखों छोटे आदेशों पर अमल करेंगे:

mv out.1 /home/user/trash
mv out.2 /home/user/trash
...

आप कुछ में देखना चाहते हो सकता है parallel विशेष रूप से विकल्प -j तथा -i इसलिए आप अप्रत्याशित रूप से अपने सर्वर को अधिभारित नहीं करते हैं।

पुनश्च। @ बर्नहार्ड की सलाह का पालन करें, जब भी आप शेल चर का उपयोग करते हैं, विशेष रूप से उपयोगकर्ता इनपुट के लिए, तो इसे उद्धृत करें! करना "{}" नहीं {}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.