जवाबों:
बैश या ksh में, फ़ाइल नामों को किसी सरणी में रखें, और उस सरणी पर उल्टे क्रम में पुनरावृति करें।
files=(/var/logs/foo*.log)
for ((i=${#files[@]}-1; i>=0; i--)); do
bar "${files[$i]}"
done
यदि ksh_arrays
विकल्प सेट है (तो यह ksh इम्यूलेशन मोड में है) ऊपर का कोड भी zsh में काम करता है । Zsh में एक सरल विधि है, जो ग्लोब क्वालीफायर के माध्यम से मैचों के क्रम को उल्टा करने के लिए है:
for f in /var/logs/foo*.log(On); do bar $f; done
POSIX में सरणियाँ शामिल नहीं हैं, इसलिए यदि आप पोर्टेबल होना चाहते हैं, तो स्ट्रिंग्स की एक सरणी को सीधे स्टोर करने का आपका एकमात्र विकल्प स्थितिगत पैरामीटर है।
set -- /var/logs/foo*.log
i=$#
while [ $i -gt 0 ]; do
eval "f=\${$i}"
bar "$f"
i=$((i-1))
done
i
और f
; बस shift
, $1
अपने कॉल के लिए उपयोग करें bar
, और [ -z $1 ]
अपने में परीक्षण करें while
।
[ -z $1 ]
और न ही [ -z "$1" ]
उपयोगी परीक्षण हैं (क्या होगा अगर पैरामीटर था *
, या एक खाली स्ट्रिंग?)। और किसी भी मामले में वे यहां मदद नहीं करते हैं: सवाल यह है कि विपरीत क्रम में लूप कैसे किया जाए।
जब तक आप पंक्ति को "कायरता वर्ण" नहीं मानते, तब तक यह कोशिश करें:
ls /var/logs/foo*.log | tac | while read f; do
bar "$f"
done
f
मेरी स्थिति में परिवर्तनशीलता को तोड़ दिया । यह उत्तर हालांकि, साधारण for
लाइन के लिए ड्रॉप-इन प्रतिस्थापन के रूप में बहुत अधिक कार्य करता है ।
यदि कोई यह पता लगाने की कोशिश कर रहा है कि अंतरिक्ष-सीमांकित स्ट्रिंग सूची पर पुनरावृति कैसे करें, तो यह काम करता है:
reverse() {
tac <(echo "$@" | tr ' ' '\n') | tr '\n' ' '
}
list="a bb ccc"
for i in `reverse $list`; do
echo "$i"
done
> ccc
> bb
> a
tac
एक हिस्सा है। लेकिन आपका समाधान भी एक अच्छा है।
tac
। हालांकि tac
यहाँ पर बिना-प्रतिक्रिया के संख्या से मुझे लगता है कि शायद OSX tac नहीं है। जिस स्थिति में @ arp के समाधान के कुछ प्रकार का उपयोग करें - वैसे भी समझना आसान है।
find /var/logs/ -name 'foo*.log' -print0 | tail -r | xargs -0 bar
आपके इच्छित तरीके को संचालित करना चाहिए (यह मैक ओएस एक्स पर परीक्षण किया गया था और मेरे पास नीचे एक चेतावनी है ...)।
खोजने के लिए आदमी पृष्ठ से:
-print0
This primary always evaluates to true. It prints the pathname of the current file to standard output, followed by an ASCII NUL character (charac-
ter code 0).
असल में, आप उन फ़ाइलों को ढूंढ रहे हैं जो आपके स्ट्रिंग + ग्लोब से मेल खाती हैं और प्रत्येक को NUL वर्ण से समाप्त करती हैं। यदि आपके फ़ाइल नाम में नई लाइनें या अन्य अजीब अक्षर हैं, तो आपको इसे अच्छी तरह से संभालना चाहिए।
tail -r
पाइप के माध्यम से मानक इनपुट लेता है और इसे उलट देता है (ध्यान दें कि सभी इनपुट को स्टडआउट में tail -r
प्रिंट करता है, और न केवल अंतिम 10 लाइनें, जो मानक डिफ़ॉल्ट है। man tail
अधिक जानकारी के लिए)।
हम फिर उसे पाइप करते हैं xargs -0
:
-0 Change xargs to expect NUL (``\0'') characters as separators, instead of spaces and newlines. This is expected to be used in concert with the
-print0 function in find(1).
यहाँ, xargs को NUL चरित्र द्वारा अलग किए गए तर्कों को देखने की उम्मीद है, जिन्हें आपने पास किया find
और उलट दिया tail
।
मेरी चेतावनी: मैंने पढ़ा है कि tail
अशक्त-समाप्त स्ट्रिंग्स के साथ अच्छा नहीं खेलता । मैक ओएस एक्स पर यह अच्छी तरह से काम करता है, लेकिन मैं गारंटी नहीं दे सकता कि सभी * निक्स के मामले में। सावधानी से चलना।
मुझे यह भी उल्लेख करना चाहिए कि GNU समानांतर का उपयोग अक्सर एक xargs
विकल्प के रूप में किया जाता है । आप यह भी देख सकते हैं।
मुझे कुछ याद आ रहा है, इसलिए दूसरों को झंकारना चाहिए।
tail -r
हालांकि समर्थन नहीं करता है ... क्या मैं कुछ गलत कर रहा हूं?
tac
एक विकल्प के रूप में उल्लेख किया है , इसलिए मैं इसके बजाय कोशिश
tail -r
OSX के लिए विशिष्ट है, और न्यूलाइन-सीमांकित इनपुट को उलट देता है, शून्य-सीमांकित इनपुट नहीं। आपका दूसरा समाधान बिल्कुल भी काम नहीं करता (आप इनपुट को पाइप कर रहे हैं ls
, जिसकी कोई परवाह नहीं है); कोई आसान तय नहीं है जो इसे मज़बूती से काम करेगा।
आपके उदाहरण में आप कई फ़ाइलों पर लूपिंग कर रहे हैं, लेकिन मुझे यह प्रश्न अपने अधिक सामान्य शीर्षक के कारण मिला, जो किसी सरणी पर लूपिंग को कवर कर सकता है, या किसी भी क्रम के आधार पर उलट सकता है।
यहाँ है कि Zsh में कैसे करें:
यदि आप किसी सरणी में तत्वों पर लूप कर रहे हैं, तो इस सिंटैक्स का उपयोग करें ( स्रोत )
for f in ${(Oa)your_array}; do
...
done
O
अगले झंडे में निर्दिष्ट आदेश के विपरीत; a
सामान्य सरणी क्रम है।
जैसा कि @Gilles ने कहा, On
आपकी ग्लॉब्ड फाइल्स को ऑर्डर करेगा, जैसे कि my/file/glob/*(On)
। ऐसा इसलिए On
है क्योंकि "रिवर्स नेम ऑर्डर है।"
Zsh तरह झंडे:
a
सरणी क्रमL
फ़ाइल की लंबाईl
लिंक की संख्याm
सुधार की तारीखn
नाम^o
रिवर्स ऑर्डर ( o
सामान्य ऑर्डर है)O
उल्टे क्रमउदाहरण के लिए, https://github.com/grml/zsh-lovers/blob/master/zsh-lovers.1.txt और http://reasoniamhere.com/2014/01/11/outrageously-useful-tips- देखें टू-गुरु-अपने-Z-खोल /
Mac OSX tac
कमांड का समर्थन नहीं करता है । @Tcdyl द्वारा समाधान तब काम करता है जब आप एक कमांड को for
लूप में बुला रहे हैं । अन्य सभी मामलों के लिए, इसके चारों ओर जाने का सबसे सरल तरीका निम्नलिखित है।
यह दृष्टिकोण आपके फ़ाइलनाम में नई सूचियाँ होने का समर्थन नहीं करता है। अंतर्निहित कारण यह है कि tail -r
इसके इनपुट को न्यूलाइन द्वारा सीमांकित किया गया है।
for i in `ls -1 [filename pattern] | tail -r`; do [commands here]; done
हालांकि, न्यूलाइन सीमा के आसपास जाने का एक तरीका है। यदि आप जानते हैं कि आपके फ़ाइल नाम में एक निश्चित वर्ण नहीं है (कहते हैं, '='), तो आप tr
इस वर्ण को बनने के लिए सभी नई सूचियों को बदलने के लिए उपयोग कर सकते हैं और फिर छँटाई कर सकते हैं। परिणाम इस प्रकार दिखेगा:
for i in `find [directory] -name '[filename]' -print0 | tr '\n' '=' | tr '\0' '\n'
| tail -r | tr '\n' '\0' | tr '=' '\n' | xargs -0`; do [commands]; done
नोट: आपके संस्करण के आधार पर tr
, यह '\0'
एक चरित्र के रूप में समर्थन नहीं कर सकता है । यह आमतौर पर सी में स्थान बदलकर सी के आसपास काम किया जा सकता है (लेकिन मुझे याद नहीं है कि वास्तव में कैसे ठीक है, क्योंकि इसे एक बार ठीक करने के बाद अब यह मेरे कंप्यूटर पर काम करता है)। यदि आपको कोई त्रुटि संदेश मिलता है, और आपको वर्कअराउंड नहीं मिल सकता है, तो कृपया इसे टिप्पणी के रूप में पोस्ट करें, इसलिए मैं आपको इसका निवारण करने में मदद कर सकता हूं।
sort -r
पहले पाइपfor
, या के माध्यम से launderls -r
।