जवाबों:
के संयोजन का उपयोग करना tr
+ tac
+paste
$ tr '.' $'\n' <<< 'arg1.arg2.arg3.arg4.arg5' | tac | paste -s -d '.'
arg5.arg4.arg3.arg2.arg1
यदि आप अभी भी बैश पसंद करते हैं, तो आप इस तरह से कर सकते हैं,
IFS=. read -ra line <<< "arg1.arg2.arg3.arg4."
let x=${#line[@]}-1;
while [ "$x" -ge 0 ]; do
echo -n "${line[$x]}.";
let x--;
done
का उपयोग कर perl
,
$ echo 'arg1.arg2.arg3.arg4.arg5' | perl -lne 'print join ".", reverse split/\./;'
arg5.arg4.arg3.arg2.arg1
यदि आप थोड़ा सा बुरा नहीं मानते हैं python
:
".".join(s.split(".")[::-1])
उदाहरण:
$ python3 -c 's="arg1.arg2.arg3.arg4.arg5"; print(".".join(s.split(".")[::-1]))'
arg5.arg4.arg3.arg2.arg1
s.split(".")
.
अलग-अलग सब्सट्रिंग्स वाली सूची बनाता है, सूची को [::-1]
उलटता है और ".".join()
उलट सूची के घटकों के साथ जुड़ता है .
।आप इसे एकल sed
आह्वान के साथ कर सकते हैं :
sed -E 'H;g;:t;s/(.*)(\n)(.*)(\.)(.*)/\1\4\5\2\3/;tt;s/\.(.*)\n/\1./'
यह पैटर्न स्पेस में एक प्रमुख न्यूलाइन प्राप्त करने के लिए होल्ड बफर का उपयोग करता है और इसे तब तक क्रमपरिवर्तन करने के लिए उपयोग करता है जब तक कि नईलाइन का किसी भी डॉट द्वारा अनुसरण नहीं किया जाता है, जिस बिंदु पर यह पैटर्न स्पेस से प्रमुख डॉट को हटा देता है और न्यूलाइन को डॉट के साथ बदल देता है।
BRE और थोड़े अलग रेगेक्स के साथ:
sed 'H
g
:t
s/\(.*\)\(\n\)\(.*\)\(\.\)\(.*\)/\1\4\5\2\3/
tt
s/\(\.\)\(.*\)\n/\2\1/'
यदि इनपुट में एक से अधिक लाइन हैं और आप प्रत्येक लाइन पर ऑर्डर को उलटना चाहते हैं:
sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/'
के साथ zsh
:
$ string=arg1.arg2.arg3.arg4.arg5
$ printf '%s\n' ${(j:.:)${(Oas:.:)string}}
arg5.arg4.arg3.arg2.arg1
खाली तत्वों को संरक्षित करने के लिए:
$ string=arg1.arg2.arg3.arg4..arg5.
$ printf '%s\n' ${(j:.:)"${(@Oas:.:)string}"}
.arg5..arg4.arg3.arg2.arg1
s:.:
: पर विभाजित .
Oa
: रिवर्स में तरह सरणी एक rray indice ओ rderj:.:
: पर शामिल हों .
।@
: "$@"
जब डबल कोट्स में ऐसा ही विस्तार होता है, तो विस्तार खाली-खाली नहीं होता है।POSIX (या bash
) समतुल्य कुछ इस तरह हो सकता है:
string=arg1.arg2.arg3.arg4..arg5.
IFS=.; set -f
set -- $string$IFS # split string into "$@" array
unset pass
for i do # reverse "$@" array
set -- "$i" ${pass+"$@"}
pass=1
done
printf '%s\n' "$*" # "$*" to join the array elements with the first
# character of $IFS
(ध्यान दें कि zsh
( sh
अनुकरण में), yash
और कुछ- pdksh
गोले के गोले उस संबंध में POSIX नहीं हैं कि वे $IFS
क्षेत्र परिसीमनकर्ता के बजाय क्षेत्र विभाजक के रूप में व्यवहार करते हैं )
जहां यह यहां दिए गए कुछ अन्य समाधानों से भिन्न है, यह है कि यह न्यूलाइन कैरेक्टर (और zsh
, एनयूएल एक या तो) विशेष रूप से व्यवहार नहीं करता है , जिसे $'ab.cd\nef.gh'
उलटा किया जाएगा $'gh.cd\nef.ab'
, $'cd.ab\ngh.ef'
या नहीं $'gh.ef.cd.ab'
।
IFS="."; set -f; set -- $string$IFS; for i; do rev="$i$IFS$rev"; done; printf '%s\n' "${rev%$IFS}"
?
for i; do
जो POSIX नहीं है (अभी तक) भले ही यह सभी POSIX गोले जो मुझे पता है) द्वारा समर्थित है। यह सिर्फ इतना है कि समाधान एक का सीधा अनुवाद है zsh
(सरणी में विभाजित करें, रिवर्स सरणी, सरणी तत्वों में शामिल हों) लेकिन पोसिक्स-ओनली ऑपरेटर्स का उपयोग करना। (मुझे लगता है कि गोले, धन्यवाद के पार लगातार काम करने के string=$string$IFS; set -- $string
लिए बदल गया है set -- $string$IFS
)।
मैं देख रहा हूं कि राहुल ने पहले से ही एक देशी बैश समाधान (दूसरों के बीच) पोस्ट किया है, जो मेरे साथ आए पहले संस्करण का एक छोटा संस्करण है:
function reversedots1() (
IFS=. read -a array <<<"$1"
new=${array[-1]}
for((i=${#array[*]} - 2; i >= 0; i--))
do
new=${new}.${array[i]}
done
printf '%s\n' "$new"
)
लेकिन मैं वहाँ नहीं रुक सका, और एक पुनरावर्ती बाश केंद्रित समाधान लिखने की आवश्यकता महसूस की:
function reversedots2() {
if [[ $1 =~ ^([^.]*)\.(.*)$ ]]
then
printf %s $(reversedots2 "${BASH_REMATCH[2]}") . "${BASH_REMATCH[1]}"
else
printf %s "$1"
fi
}