मैं फ़ाइलें कैसे खोज सकता हूं और फिर उन्हें स्थानांतरित करने के लिए xargs का उपयोग कर सकता हूं?


28

मैं कुछ फाइलें ढूंढना चाहता हूं और फिर उन्हें स्थानांतरित करना चाहता हूं।

मैं के साथ फाइल पा सकते हैं:

$ find /tmp/ -ctime -1 -name x*

मैंने उन्हें अपनी ~/playनिर्देशिका में ले जाने की कोशिश की :

$ find /tmp/ -ctime -1 -name x* | xargs mv ~/play/

लेकिन वह काम नहीं किया। जाहिर है एमवी को दो तर्कों की जरूरत है।
सुनिश्चित नहीं हैं कि अगर (या कैसे) mv कमांड में xargs 'करंट आइटम' का संदर्भ दिया जाए?


3
क्यूं कर? आप प्लेसहोल्डर का उपयोग इसके साथ कर सकते हैं -I: find . | xargs -I'{}' mv '{}' ~/play/लेकिन जैसा कि आदमी कहता है, कि "इम्प्लाईज -xऔर -L 1।" तो कोई फायदा नहीं हुआ। बेहतर है कि इसे सरल रखें और उपयोग करेंfind . -exec mv '{}' ~/play/ \;
मैनटवर्क

अगर आप बुरा नहीं
मानेंगे

जैसा मैंने महसूस नहीं किया था, ठीक वैसा ही आपके कारण से मैंने पूछा। अगर ड्राव स्लोन निहित विकल्पों पर नोट जोड़ते हैं, तो उनका जवाब उतना ही अच्छा होगा जितना मैं लिख सकता हूं। इतना बेहतर है कि साथ जाओ।
मैनटवर्क

के संभावित डुप्लिकेट खोजें पैटर्न और चाल
SLM

@manatwork मैंने उन बिंदुओं को दर्शाने के लिए अपना उत्तर संपादित किया है :)
Drav Sloan

जवाबों:


43

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

आप के -Iविकल्प का उपयोग कर सकते हैं xargs:

find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/

जो एक समान तंत्र में findऔर के लिए काम करता है {}। मैं आपके -nameतर्क को भी उद्धृत करूँगा (क्योंकि xवर्तमान निर्देशिका में शुरू होने वाली फ़ाइल फ़ाइल-ग्लोब होगी और खोजने के तर्क के रूप में पारित हो जाएगी - जो अपेक्षित व्यवहार नहीं देगी!)।

हालाँकि, जैसा कि मैनटवर्क द्वारा बताया गया है, जैसा कि xargsमैन पेज में विस्तृत है :

   -I replace-str
          Replace occurrences of replace-str in the initial-arguments with
          names read from standard input.  Also, unquoted  blanks  do  not
          terminate  input  items;  instead  the  separator is the newline
          character.  Implies -x and -L 1.

ध्यान देने वाली महत्वपूर्ण बात यह है कि -L 1इसका मतलब यह है कि एक समय में आउटपुट की केवल एक पंक्ति को findसंसाधित किया जाएगा। इसका अर्थ है कि यह वाक्यात्मक रूप से समान है:

find /tmp/ -ctime -1 -name "x*" -exec mv '{}' ~/play/

(जो प्रत्येक फ़ाइल के mvलिए एकल ऑपरेशन निष्पादित करता है )।

यहां तक ​​कि ग्नू -0xargs तर्क और तर्क का उपयोग करने पर find -print0बिल्कुल समान व्यवहार का कारण बनता है -I- यह clone()प्रत्येक फ़ाइल के लिए एक प्रक्रिया है mv:

find . -name "x*" -print0 | strace xargs -0 -I '{}' mv '{}' /tmp/other

.
.
read(0, "./foobar1/xorgslsala11\0./foobar1"..., 4096) = 870
mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =     0x7fbb82fad000
open("/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26066, ...}) = 0
mmap(NULL, 26066, PROT_READ, MAP_SHARED, 3, 0) = 0x7fbb82fa6000
close(3)                                = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,         child_tidptr=0x7fbb835af9d0) = 661
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 661
--- SIGCHLD (Child exited) @ 0 (0) ---
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,         child_tidptr=0x7fbb835af9d0) = 662
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 662
--- SIGCHLD (Child exited) @ 0 (0) ---
.
.
.

फ़ाइल के नाम में न्यूलाइन, सिंगल कोट, डबल कोट या बैकस्लैश कैरेक्टर नहीं हैं।
स्टीफन चेज़लस

17

GNU टूल्स के साथ:

find /tmp/ -ctime -1 -name 'x*' -print0 |
  xargs -r0 mv -t ~/play/

-t( --target) विकल्प जीएनयू विशिष्ट है। -print0, -r, -0, जबकि गैर मानक और GNU में उद्भव भी कुछ BSDs पर जैसे कुछ अन्य कार्यान्वयन में पाए जाते हैं।

POSIXly:

find /tmp/ -ctime -1 -name 'x*' -exec sh -c '
  exec mv "$@" ~/play/' sh {} +

दोनों mvआवश्यक के रूप में कुछ आदेशों को चलाते हैं और फ़ाइल नाम में जो भी वर्ण होते हैं वे काम कर सकते हैं। जीएनयू में वह लाभ हो सकता है जो पहले बैच को स्थानांतरित findकरने के दौरान फाइलों की तलाश में रहता है mv

सावधान रहें कि सभी फाइलें और निर्देशिकाएं एक निर्देशिका में समाप्त हो जाएंगी, यदि विभिन्न निर्देशिकाओं में कई फाइलों का एक ही नाम हो तो झड़पों से सावधान रहें।


यह समाधान काफी बेहतर प्रदर्शन कर रहा है, क्योंकि यह कहता है mvसभी तर्कों के लिए एक बार (या सभी के लिए -Lया -n, अगर आपूरित हो)। अन्यथा, mvप्रत्येक फ़ाइल के लिए कॉलिंग पुरानी (और धीमी) तेजी से हो जाएगी।
r2evans

1

शायद यह आदेश अब संभव है और 2013 में वापस नहीं आया था, लेकिन यह मेरे लिए पूरी तरह से काम करता है:

ls pattern* | xargs mv -t DESTINATION/

-tकुंजी पुट गंतव्य फ़ोल्डर पहले, को मुक्त mvआदेश सभी पिछले तर्क के रूप में सिर्फ फाइलों में ले जाया जा करने के लिए।


1
यह मेरे लिए काम करने वाला सबसे सरल उपाय था
ptetteh227

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