Yanıtlar:
tr
+ tac
+ Kombinasyonunu kullanmapaste
$ tr '.' $'\n' <<< 'arg1.arg2.arg3.arg4.arg5' | tac | paste -s -d '.'
arg5.arg4.arg3.arg2.arg1
Hala bash'ı tercih ediyorsanız, bu şekilde yapabilirsiniz,
IFS=. read -ra line <<< "arg1.arg2.arg3.arg4."
let x=${#line[@]}-1;
while [ "$x" -ge 0 ]; do
echo -n "${line[$x]}.";
let x--;
done
Kullanmak perl
,
$ echo 'arg1.arg2.arg3.arg4.arg5' | perl -lne 'print join ".", reverse split/\./;'
arg5.arg4.arg3.arg2.arg1
Biraz sakıncası yoksa python
:
".".join(s.split(".")[::-1])
Misal:
$ python3 -c 's="arg1.arg2.arg3.arg4.arg5"; print(".".join(s.split(".")[::-1]))'
arg5.arg4.arg3.arg2.arg1
s.split(".")
.
ayrılmış alt dizeler içeren bir liste oluşturur, listeyi [::-1]
tersine çevirir ve ".".join()
ters listenin bileşenlerini ile birleştirir .
.Tek bir sed
çağrı ile yapabilirsiniz :
sed -E 'H;g;:t;s/(.*)(\n)(.*)(\.)(.*)/\1\4\5\2\3/;tt;s/\.(.*)\n/\1./'
bu, desen alanında önde gelen bir yeni satır elde etmek için tutma arabelleğini kullanır ve yeni satır artık izleyen noktadan sonra, nokta noktasını model uzayından kaldırarak yeni satırı bir nokta ile değiştirene kadar permütasyon yapmak için kullanır.
BRE ve biraz farklı regex ile:
sed 'H
g
:t
s/\(.*\)\(\n\)\(.*\)\(\.\)\(.*\)/\1\4\5\2\3/
tt
s/\(\.\)\(.*\)\n/\2\1/'
Giriş birden fazla satırdan oluşuyorsa ve her satırdaki sıralamayı tersine çevirmek istiyorsanız:
sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/'
İle zsh
:
$ string=arg1.arg2.arg3.arg4.arg5
$ printf '%s\n' ${(j:.:)${(Oas:.:)string}}
arg5.arg4.arg3.arg2.arg1
Boş elemanları korumak için:
$ string=arg1.arg2.arg3.arg4..arg5.
$ printf '%s\n' ${(j:.:)"${(@Oas:.:)string}"}
.arg5..arg4.arg3.arg2.arg1
s:.:
: bölünmüş .
Oa
: Ters sıralama dizisi bir rray indisi o orderj:.:
: katılın .
.@
: "$@"
çift tırnak içine alındığında genişletme gibi genişleme boş kaldırma işleminden geçmez.POSIX (veya bash
) eşdeğeri aşağıdaki gibi olabilir:
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
emülasyonda) yash
ve bazı pdksh
tabanlı kabukların, bu nedenle $IFS
alan sınırlayıcı yerine alan ayırıcısı olarak işlem görmeleri açısından POSIX olmadığını unutmayın )
Burada verilen diğer bazı çözümler farklıdır nerede satır karakteri tedavi etmez (ve söz konusu zsh
her iki NULL bir) özel olarak, yani $'ab.cd\nef.gh'
için geri alınması $'gh.cd\nef.ab'
değil, $'cd.ab\ngh.ef'
ya da $'gh.ef.cd.ab'
.
IFS="."; set -f; set -- $string$IFS; for i; do rev="$i$IFS$rev"; done; printf '%s\n' "${rev%$IFS}"
nedir?
for i; do
bildiğim tüm POSIX kabukları tarafından desteklense bile POSIX (henüz) dışında ). Sadece bu çözüm, doğrudan zsh
POSIX operatörleri kullanarak bir dizinin doğrudan dizisidir (dizi, ters dizi, birleştirme dizi elemanları). (Ben değiştim string=$string$IFS; set -- $string
için set -- $string$IFS
, o kabukları tutarlı iş gibi görünüyor olarak sayesinde).
Rahul'ın zaten (diğerlerinin yanı sıra) yerli bir bash çözümü gönderdiğini görüyorum , ki bu ilk bulduğumdan daha kısa bir versiyon:
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"
)
ama orada duramadım ve özyinelemeli bash merkezli bir çözüm yazma gereğini hissettim:
function reversedots2() {
if [[ $1 =~ ^([^.]*)\.(.*)$ ]]
then
printf %s $(reversedots2 "${BASH_REMATCH[2]}") . "${BASH_REMATCH[1]}"
else
printf %s "$1"
fi
}
Bir awk
cevap görmedim , işte bir tane:
echo 'arg1.arg2.arg3' | awk -F. '{for (i=NF; i>0; --i) printf "%s%s", (i<NF ? "." : ""), $i; printf "\n"}'