শব্দ দ্বারা কোনও ভেরিয়েবলের বিষয়বস্তু বিপরীত করা


13

সুতরাং আমি যদি একটি পরিবর্তনশীল পেয়েছি

VAR='10 20 30 40 50 60 70 80 90 100'

এবং এটি প্রতিধ্বনি করুন

echo "$VAR"
10 20 30 40 50 60 70 80 90 100

যাইহোক, স্ক্রিপ্টের আরও নিচে আমার এই ভেরিয়েবলের ক্রমটি বিপরীত করা দরকার যাতে এটির মতো কিছু প্রদর্শিত হয়

echo "$VAR" | <code to reverse it>
100 90 80 70 60 50 40 30 20 10

আমি রেভ ব্যবহার করার চেষ্টা করেছি এবং এটি আক্ষরিকভাবে সমস্ত কিছু বিপরীত করেছে তাই এটি প্রকাশিত হয়েছিল

echo "$VAR" | rev
001 09 08 07 06 05 04 03 02 01

2
এই অনুরূপ প্রশ্নের উত্তরে আপনি কিছু দরকারী পরামর্শ পেতে পারেন: কোনও আইপি ঠিকানা পিছন দিকে কীভাবে পড়বেন? (পিরিয়ডের জায়গায় কেবল স্থান বিভাজকগুলির জন্য সামঞ্জস্য করা দরকার)
স্টিল্ড্রাইভার

উত্তর:


21

জিএনইউ সিস্টেমে, বিড়ালের বিপরীতটি হ'ল:

$ tac -s" " <<< "$VAR "            # Please note the added final space.
100 90 80 70 60 50 40 30 20 10

চিয়ার্স! কৌতুকটি করেছে। আমি এখনও অনেক কিছু শিখতে পেরেছি
এলিস্টায়ার হার্ডি

@ ঝনকুগেলম্যান প্রতিধ্বনি ব্যতীত আউটপুটটির অতিরিক্ত নতুন লাইন রয়েছে, echo $'100 \n90 80 70 60 50 40 30 20 10'
এটির

বর্তমান tac -s" " <<< "$VAR "সংস্করণ সহ, এটি এখনও একটি শীর্ষস্থানীয় ফাঁকা রেখা সন্নিবেশ করায়, একটি পূর্ববর্তী স্থান যুক্ত করেছে এবং অনুমানের printf '\n%s ' "$reversed_VAR"পরিবর্তে নতুন রেখাচিত্রটি বাদ দেয় (যেমন প্রত্যাশার পরিবর্তে printf '%s\n' "$reversed_VAR")
স্টাফেন চ্যাজেলাস

@ ডন_ক্রিসটি আসল উত্তর: echo $(tac -s" " <<< $VAR)পেছনের স্থান নেই কারণ $(…)আইএফএস থাকলে নতুন লাইনের স্থান এবং স্পেসগুলি সরিয়ে দেয়। আমার সমাধান শীঘ্রই সংশোধন করা হবে, ধন্যবাদ।
sorontar

6

একটি সংক্ষিপ্ত তালিকার জন্য এবং একটি পরিবর্তনীয় ক্ষেত্রে শেলটি নিজেই দ্রুততম সমাধান:

var="10 20 30 40 50 60 70 80 90 100"
set -- $var; unset a 
for ((i=$#;i>0;i--)); do
    printf '%s%s' "${a:+ }" "${!i}"
    a=1
done
echo

আউটপুট:

100 90 80 70 60 50 40 30 20 10 

দ্রষ্টব্য: স্প্লিট অপারেশনটি set -- $varএখানে ব্যবহৃত সঠিক স্ট্রিংয়ের জন্য নিরাপদ তবে স্ট্রিংটিতে ওয়াইল্ডকার্ড অক্ষর ( *, ?বা []) থাকলে তা হবে না । প্রয়োজনে এটি set -fবিভক্ত হওয়ার আগে এড়ানো যেতে পারে । একই দ্রষ্টব্য নিম্নলিখিত সমাধানগুলির জন্যও বৈধ।

অথবা, যদি আপনি বিপরীত তালিকার সাথে আরও কিছু ভেরিয়েবল সেট করতে চান:

var="10 20 30 40 50 60 70 80 90 100"
set -- $var
for i; do out="$i${out:+ }$out"; done
echo "$out"

বা শুধুমাত্র অবস্থানগত পরামিতি ব্যবহার করে।

var="10 20 30 40 50 60 70 80 90 100"
set -- $var
a=''
for    i
do     set -- "$i${a:+ $@}"
       a=1
done
echo "$1"

বা শুধুমাত্র একটি ভেরিয়েবল ব্যবহার করে (যা নিজে নিজেই বিভিন্ন হতে পারে):
দ্রষ্টব্য: এই সমাধানটি গ্লোবিং বা আইএফএস দ্বারা প্রভাবিত হয় না।

var="10 20 30 40 50 60 70 80 90 100"

a=" $var"
while [[ $a ]]; do
    printf '<%s>' "${a##* }"
    var="${a% *}"
done

2

awk উদ্ধার করতে

$ var='10 20 30 40 50 60 70 80 90 100'

$ echo "$var" | awk '{for(i=NF; i>0; i--) printf i==1 ? $i"\n" : $i" "}'
100 90 80 70 60 50 40 30 20 10


সহ perl, সৌজন্যে কিভাবে পিছন দিকে একটি আইপি ঠিকানা পড়তে? @ স্টিলড্রাইভার শেয়ার করেছেন

$ echo "$var" | perl -lane '$,=" "; print reverse @F'
100 90 80 70 60 50 40 30 20 10


অথবা bashনিজেই স্ট্রিংটিকে অ্যারেতে রূপান্তর করে

$ arr=($var)    
$ for ((i=${#arr[@]}-1; i>=0; i--)); do printf "${arr[i]} "; done; echo
100 90 80 70 60 50 40 30 20 10 

2

প্রক্রিয়াজাতভাবে সম্পূর্ণরূপে এটি করতে আপনি ব্যাশ বৈশিষ্ট্যগুলি যেমন অ্যারে ব্যবহার করতে পারেন:

#!/bin/bash
VAR="10 20 30 40 50 60 70 80 90 100"
a=($VAR); rev_a=()
for ((i=${#a[@]}-1;i>=0;i--)); do rev_a+=( ${a[$i]} ); done; 
RVAR=${rev_a[*]}; 

এটি করার দ্রুততম উপায় সম্পর্কে এটি হওয়া উচিত provided VAR খুব বড় নয়।


তবে এটি ভেরিয়েবলগুলিতে প্রসারিত হবে না যার মান ওয়াইল্ডকার্ড অক্ষর রয়েছে (যেমন VAR='+ * ?')। ব্যবহার করুন set -o noglobবা set -fএটি ঠিক করতে। আরও সাধারণভাবে, $IFSবিভাজন + গ্লোব অপারেটর ব্যবহার করার সময় গ্লোব্বিংয়ের মান এবং স্থিতি বিবেচনা করা ভাল ধারণা । কোন এটি সামান্য অর্থে যে অপারেটর ব্যবহার করে তোলে rev_a+=( ${a[$i]} ), rev_a+=( "${a[$i]}" )আরো অনেক জানার জন্য হবে।
স্টাফেন চেজেলাস


1

পাইথন যাদুবিদ্যার কিছুটা ব্যবহার করুন:

bash-4.3$ VAR='10 20 30 40 50 60 70 80 90 100'
bash-4.3$ python -c 'import sys;print " ".join(sys.argv[1].split()[::-1])'  "$VAR" 
100 90 80 70 60 50 40 30 20 10

এটি যেভাবে কাজ করে তা মোটামুটি সহজ:

  • আমরা "$VAR"দ্বিতীয় কমান্ড লাইন প্যারামেন্টার হিসাবে উল্লেখ করি sys.argv[1]( -cবিকল্পের সাথে প্রথম প্যারামিটারটি সর্বদা কেবল এটি - -cনিজেই "$VAR"individual ভেরিয়েবলটি পৃথক শব্দের মধ্যে বিভক্ত হওয়া রোধ করার জন্য চারপাশে উদ্ধৃতিটি লক্ষ্য করুন (যা হিজি অজগর নয়, শেল দিয়ে করেছে)
  • এরপরে আমরা .split()পদ্ধতিটি ব্যবহার করি , এটি স্ট্রিংয়ের তালিকায় ভাঙতে
  • [::-1]অংশটি তালিকার বিপরীতে পেতে কেবল স্লাইস সিনট্যাক্স প্রসারিত
  • অবশেষে আমরা সবকিছুতে একসাথে ফিরে এক স্ট্রিং এর সাথে " ".join()প্রিন্ট আউট করব

তবে যারা বড় পাইথন ভক্ত নন, আমরা AWKমূলত একই জিনিসটি ব্যবহার করতে পারি: বিভক্ত হয়ে প্রিন্ট অ্যারে বিপরীতে:

 echo "$VAR" | awk '{split($0,a);x=length(a);while(x>-1){printf "%s ",a[x];x--};print ""}'
100 90 80 70 60 50 40 30 20 10 

1
বা কিছুটা পরিষ্কারpython3 -c 'import sys;print(*reversed(sys.argv[1:]))' $VAR
ইরুভার

@iruvar, ক্লিনার নয় , এটি $IFSসঠিক অক্ষর রয়েছে কিনা তা নিশ্চিত না করে এবং গ্লোব অংশটি অক্ষম না করে শেলের বিভাজন + গ্লোব অপারেটরকে ডাকে ।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস, যথেষ্ট সত্য - পাইথনের অংশটি এখনও পরিষ্কার (আইএমএইচও) রয়েছে। সুতরাং, "$VAR"ফলন ফিরে যাচ্ছিpython3 -c 'import sys;print(*reversed(sys.argv[1].split()))' "$VAR"
iruvar

1

zsh:

print -r -- ${(Oa)=VAR}

$=VARsplits $VARউপর $IFS(Oa)বিপরীত অ্যারে ক্রমানুসারে ফলাফলের তালিকা অর্ডার করে। print -r --(যেমন ksh) এর মতো echo -E -( zshনির্দিষ্ট) এর একটি নির্ভরযোগ্য সংস্করণecho : এর আর্গুমেন্টগুলি স্থান দ্বারা পৃথক করা হয়, নিউলাইন দ্বারা সমাপ্ত করে প্রিন্ট করে।

আপনি যদি কেবলমাত্র স্পেসে বিভক্ত করতে চান, এবং যা $IFS(স্পেস, ট্যাব, নিউলাইন, ডিফল্টরূপে নুল) রয়েছে তার উপর নয়, হয় স্থান বরাদ্দ করুন $IFS, বা স্পষ্ট বিভাজন যেমন:

print -r -- ${(Oas: :)VAR}

বিপরীত সংখ্যার ক্রম অনুসারে বাছাই করতে:

$ VAR='50 10 20 90 100 30 60 40 70 80'
$ print -r -- ${(nOn)=VAR}
100 90 80 70 60 50 40 30 20 10

পজিক্লি (এর সাথে এটিও কাজ করবে bash):

শেল বিল্টিন ( printfকিছু শেল ছাড়া ) কেবলমাত্র ব্যবস্থার সাথে (সংক্ষিপ্ত মান সহ ভেরিয়েবলের জন্য আরও ভাল):

unset -v IFS # restore IFS to its default value of spc, tab, nl
set -o noglob # disable glob
set -- $VAR # use the split+glob operator to assign the words to $1, $2...

reversed_VAR= sep=
for i do
  reversed_VAR=$i$sep$reversed_VAR
  sep=' '
done
printf '%s\n' "$reversed_VAR"

সঙ্গে awk(বড় ভেরিয়েবল, বিশেষ করে সঙ্গে জন্য ভালো bash, কিন্তু (বা একটি একক যুক্তি) আর্গুমেন্ট আকারের সীমা পর্যন্ত):

 awk '
   BEGIN {
     n = split(ARGV[1], a);
     while (n) {printf "%s", sep a[n--]; sep = " "}
     print ""
   }' "$VAR"

0

অসুন্দর POSIX সফ্টওয়্যার সরঞ্জাম এক-লাইনের:

echo `echo $VAR | tr ' ' '\n' | sort -nr`
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.