Jawaban:
Menggunakan kombinasi tr+ tac+paste
$ tr '.' $'\n' <<< 'arg1.arg2.arg3.arg4.arg5' | tac | paste -s -d '.'
arg5.arg4.arg3.arg2.arg1Jika Anda masih lebih suka bash, Anda bisa melakukannya dengan cara ini,
IFS=. read -ra line <<< "arg1.arg2.arg3.arg4."
let x=${#line[@]}-1;
while [ "$x" -ge 0 ]; do
echo -n "${line[$x]}.";
let x--;
doneMenggunakan perl,
$ echo 'arg1.arg2.arg3.arg4.arg5' | perl -lne 'print join ".", reverse split/\./;'
arg5.arg4.arg3.arg2.arg1Jika Anda tidak keberatan sedikit python:
".".join(s.split(".")[::-1])
Contoh:
$ python3 -c 's="arg1.arg2.arg3.arg4.arg5"; print(".".join(s.split(".")[::-1]))'
arg5.arg4.arg3.arg2.arg1
s.split(".")membuat daftar yang berisi .substring yang terpisah, [::-1]membalik daftar dan ".".join()bergabung dengan komponen dari daftar terbalik ..Anda dapat melakukannya dengan satu sedpermintaan:
sed -E 'H;g;:t;s/(.*)(\n)(.*)(\.)(.*)/\1\4\5\2\3/;tt;s/\.(.*)\n/\1./'
ini menggunakan buffer penahan untuk mendapatkan baris baru di ruang pola dan menggunakannya untuk melakukan permutasi sampai baris baru tidak lagi diikuti oleh titik mana titik itu menghapus titik terkemuka dari ruang pola dan menggantikan baris baru dengan titik.
Dengan BRE dan regex yang sedikit berbeda:
sed 'H
g
:t
s/\(.*\)\(\n\)\(.*\)\(\.\)\(.*\)/\1\4\5\2\3/
tt
s/\(\.\)\(.*\)\n/\2\1/'
Jika input terdiri dari lebih dari satu baris dan Anda ingin membalik urutan pada setiap baris:
sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/'
Dengan zsh:
$ string=arg1.arg2.arg3.arg4.arg5
$ printf '%s\n' ${(j:.:)${(Oas:.:)string}}
arg5.arg4.arg3.arg2.arg1
Untuk mempertahankan elemen kosong:
$ string=arg1.arg2.arg3.arg4..arg5.
$ printf '%s\n' ${(j:.:)"${(@Oas:.:)string}"}
.arg5..arg4.arg3.arg2.arg1
s:.:: terbelah .Oa: sort array secara terbalik sebuah indray rray o rderj:.:: bergabunglah ..@: lakukan "$@"ekspansi-like ketika dalam tanda kutip ganda sehingga ekspansi tidak mengalami penghapusan-kosong.bashSetara POSIX (atau ) dapat berupa sesuatu seperti:
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
(perhatikan bahwa zsh(dalam shemulasi), yashdan beberapa pdkshcangkang berbasis bukan POSIX dalam hal ini karena mereka memperlakukan $IFSsebagai pemisah medan alih-alih pembatas lapangan)
Di mana ia berbeda dari beberapa solusi lain yang diberikan di sini adalah bahwa ia tidak memperlakukan karakter baris baru (dan dalam kasus zsh, yang NUL baik) khususnya, yang $'ab.cd\nef.gh'akan dibalik ke $'gh.cd\nef.ab', bukan $'cd.ab\ngh.ef'atau $'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; doyang bukan POSIX (belum) bahkan jika itu didukung oleh semua kerang POSIX yang saya tahu). Hanya saja solusi itu adalah terjemahan langsung dari solusi tersebut zsh(dipecah menjadi array, array terbalik, bergabung dengan elemen array) tetapi menggunakan operator POSIX-only. (Saya telah mengubah string=$string$IFS; set -- $stringke set -- $string$IFSyang tampaknya bekerja secara konsisten di shell, terima kasih).
Saya melihat Rahul sudah memposting solusi bash asli (antara lain), yang merupakan versi lebih pendek dari yang pertama saya buat:
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"
)
tapi saya tidak bisa berhenti di situ, dan merasa perlu untuk menulis solusi bash-centric rekursif:
function reversedots2() {
if [[ $1 =~ ^([^.]*)\.(.*)$ ]]
then
printf %s $(reversedots2 "${BASH_REMATCH[2]}") . "${BASH_REMATCH[1]}"
else
printf %s "$1"
fi
}
Tidak melihat awkjawaban, jadi ini satu:
echo 'arg1.arg2.arg3' | awk -F. '{for (i=NF; i>0; --i) printf "%s%s", (i<NF ? "." : ""), $i; printf "\n"}'