একটি স্ট্রিংয়ে ডট-সীমিত উপাদানগুলির বিপরীত ক্রম


14

আমার মতো ইনপুট স্ট্রিং রয়েছে:

arg1.arg2.arg3.arg4.arg5

আমি যে আউটপুটটি চাই তা হ'ল:

arg5.arg4.arg3.arg2.arg1

এটি সর্বদা 5 টি আর্গের নয়, 2 থেকে 10 হতে পারে।

আমি কীভাবে এটি বাশ স্ক্রিপ্টে করতে পারি?

উত্তর:


22
  • 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

2
বাহ, আমি কেবল পার্ল সমাধান পোস্ট করতে
যাচ্ছিলাম

10

আপনি যদি একটি সামান্য বিট আপত্তি না 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()বিপরীত তালিকার উপাদানগুলির সাথে যোগ করে .

5

আপনি এটি একটি একক অনুরোধ দিয়ে করতে পারেন sed:

sed -E 'H;g;:t;s/(.*)(\n)(.*)(\.)(.*)/\1\4\5\2\3/;tt;s/\.(.*)\n/\1./'

এটি হোল্ড বাফারটিকে প্যাটার্ন স্পেসে শীর্ষস্থানীয় নিউলাইনটি পেতে ব্যবহার করে এবং নিউলাইনটি আর কোনও বিন্দু অনুসরণ না করে যতক্ষণ না এটি প্যাটার্ন স্পেস থেকে শীর্ষস্থানীয় বিন্দুটিকে সরিয়ে দেয় এবং একটি ডট দিয়ে নতুন লাইনটি প্রতিস্থাপন করে until
বিআরই এবং কিছুটা আলাদা রেজেক্স সহ:

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/'

3

এসইডি সমাধান:

sed 's/\./\n/g' yourFile | tac | sed ':a; $!{N;ba};s/\n/./g'

3

সাথে 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 rder
  • j:.:: যোগ দিন .
  • @: "$@"ডাবল এক্সটেনশনগুলি করুন যখন ডাবল কোটে থাকে যাতে প্রসারণটি খালি-অপসারণের মধ্য দিয়ে যায় না।

পসিক্স (বা 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ভিত্তিক শেলগুলি পজিক্স নয় যে তারা $IFSক্ষেত্রের সীমানার পরিবর্তে ক্ষেত্র বিভাজক হিসাবে বিবেচনা করে )

এখানে প্রদত্ত অন্যান্য সমাধানগুলির থেকে যেখানে এটি পৃথক হয়েছে তা হ'ল এটি নতুন লাইন চরিত্রটিকে (এবং zshএর মধ্যেও NUL একটিকে) বিশেষভাবে বিবেচনা করে না, এটি $'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যা পসিক্স নয় তবে (এখনও) এটি আমার জানা সমস্ত পসিক্স শেল দ্বারা সমর্থিত হলেও)। এটি ঠিক যে সমাধানটি হ'ল একটি সরাসরি অনুবাদ zsh(অ্যারেতে বিভক্ত, বিপরীতে অ্যারে, অ্যারে উপাদানগুলিতে যোগদান করুন) তবে কেবল পসিক্স-কেবল অপারেটর ব্যবহার করে। ( শেলগুলি জুড়ে ধারাবাহিকভাবে কাজ string=$string$IFS; set -- $stringকরার set -- $string$IFSমতো বলে আমি এটি পরিবর্তন করেছি , ধন্যবাদ)।
স্টাফেন চেজেলাস

2

আমি দেখছি রাহুল ইতিমধ্যে একটি নেটিভ বাশ সলিউশন পোস্ট করেছেন (অন্যদের মধ্যে), এটি আমি প্রকাশিত প্রথমটির একটি সংক্ষিপ্ত সংস্করণ:

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
}

2

কোনও awkউত্তর দেখেনি , সুতরাং এখানে একটি:

 echo 'arg1.arg2.arg3' | awk -F. '{for (i=NF; i>0; --i) printf "%s%s", (i<NF ? "." : ""), $i; printf "\n"}'

1

খাঁটি বাশ, ইনপুট নেওয়ার সময়কাল প্রয়োজন:

echo 'foo.bar.baz.' | ( while read -d . f;do g="$f${g+.}$g" ;done;echo "$g" )

printf %s "$g"বিন্দুযুক্ত উপাদানগুলির কোনও হাইফেন দিয়ে শুরু করতে পারলে ব্যবহার করুন ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.