कैसे उपखंडों में फ़ाइलों को खोजने के लिए और उन्हें एक ही आदेश में फ़ाइल नाम से सॉर्ट करें?


9

एक सामान्य खोज के परिणाम का उपयोग कर find . ! -path "./build*" -name "*.txt":

./tool/001-sub.txt
./tool/000-main.txt
./zo/001-int.txt
./zo/id/002-and.txt
./as/002-mod.txt

और जब के साथ हल sort -n:

./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt

हालांकि वांछित उत्पादन है:

./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt

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

संपादित करें : उदाहरण को और अधिक जटिल बनाएं क्योंकि उपनिर्देशिका संरचना में एक से अधिक स्तर शामिल हो सकते हैं।


2
यह सवाल मैंने SO पर पूछा: stackoverflow.com/questions/3222810/…
camh

@camh - यदि संभव हो तो मैं केवल यूनिक्स कमांड का उपयोग करना चाहूंगा। किसी भी मामले में मेरा सवाल आपका एक डुप्लिकेट है। क्या आप इस धागे का सबसे अच्छा समाधान स्थानांतरित कर सकते हैं (मूल रास्ते के लिए एक लिंक रखें) ताकि मैं समाधान के रूप में चिह्नित कर सकूं?
11'11

अगर @ शॉन ने मेरी टिप्पणी में सुझाए गए बदलाव ( -printfइसके बजाय उपयोग awk) किए हैं, तो मुझे लगता है कि यह सबसे अच्छा समाधान है। मैंने इस पद्धति का उपयोग करने के लिए अपने मूल कार्यान्वयन को फिर से काम किया है।
camh

जवाबों:


9

आपको अंतिम फ़ील्ड ( /फ़ील्ड विभाजक के रूप में विचार करके) को सॉर्ट करने की आवश्यकता है । दुर्भाग्य से, मैं एक ऐसे उपकरण के बारे में नहीं सोच सकता जो खेतों की संख्या भिन्न होने पर ऐसा sort -kकर सकता है (यदि केवल नकारात्मक मान ले सकता है)।

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

find . ! -path "./build*" -name "*.txt" |\
    awk -vFS=/ -vOFS=/ '{ print $NF,$0 }' |\
    sort -n -t / |\
    cut -f2- -d/

वह awkआदेश कहता है कि क्षेत्र विभाजक के FS लिए सेट है /; यह फ़ील्ड्स को पढ़ने के तरीके को प्रभावित करता है। उत्पादन क्षेत्र विभाजक OFS भी करने के लिए सेट कर दिया जाता /; यह रिकॉर्ड को प्रिंट करने के तरीके को प्रभावित करता है। अगला कथन कहता है कि अंतिम कॉलम प्रिंट करें ( NFरिकॉर्ड में फ़ील्ड्स की संख्या है, इसलिए यह अंतिम फ़ील्ड का इंडेक्स भी होता है) और साथ ही पूरे रिकॉर्ड ( $0संपूर्ण रिकॉर्ड); यह उन दोनों के बीच ओएफएस के साथ मुद्रित करेगा। फिर सूची sortएड है, /जिसे क्षेत्र विभाजक के रूप में माना जाता है - चूंकि हमारे पास रिकॉर्ड में पहला नाम है, यह उसी के आधार पर छाँटेगा। फिर cutप्रिंट केवल 2 क्षेत्रों को अंत के माध्यम से फिर /से क्षेत्र विभाजक के रूप में मानते हैं ।


3
चूंकि यह खोज (1) के साथ है, आप awk भाग को छोड़ सकते हैं और उपयोग कर सकते हैं-printf '%f/%p\n'
कैम

वास्तव में हमारा सेटअप थोड़ा अधिक जटिल है। इसमें वैरिएबल सबडिर डेप्थ्स शामिल हैं। इस तथ्य को प्रतिबिंबित करने के लिए प्रश्न संपादित किया। पहली बार में इसे शामिल नहीं करने के लिए मेरी माफी।
unode

1
@ यूनोड: शॉन का समाधान चर गहराई को ठीक से संभालता है, यह इस समस्या के लिए विहित समाधान है (मामूली बदलावों तक)।
गिल्स एसओ- बुराई को रोकें '23

4

मैं आउटपुट नाम और पथ के लिए '-fff' फाइल का उपयोग करता हूं, नाम से छांटता हूं, और अंतिम चरण में नाम काट देता हूं। '###' सिर्फ एक मार्कर है, काटने में मदद करने के लिए।

find -name "*.txt" -printf "%f###%p\n" | sort -n | sed 's/.*###//'

% f फाइलनाम को प्रिंट करता है,% p पूरे पथ को।

मैंने इसे एक पंक्ति में लाने के लिए खोज-कमान को सरल बनाया, निश्चित रूप से आप ! -path "./build*"भाग छोड़ देंगे ।


3

Zsh में ≥4.3.10:

print -l -- **/*.txt~build*(oe\''REPLY=${REPLY:t}'\')
  • **/*.txt*.txtवर्तमान निर्देशिका और इसके उपनिर्देशिकाओं में पुनरावर्ती मेल खाता है ।
  • ~build* उन मेलों को बाहर करता है जिनका पाठ build*(जैसे ! -path './build*') से शुरू होता है । (आपको setopt extended_globपहले आवश्यकता है ।)
  • (oe\''…'\')एक छँटाई दस्ताने योग्य हैREPLY=…लौटने के लिए स्ट्रिंग से सॉर्ट करने के लिए स्ट्रिंग का निर्माण करता है।
  • ${REPLY:t}पथ का बेसनेम ("पूंछ") है।

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