বাশ স্ক্রিপ্ট: প্রতিটি অক্ষরে বিভক্ত শব্দ


17

আমি কীভাবে একটি শব্দের অক্ষর পৃথক লাইনে প্রতিটি বর্ণ সহ আলাদা করতে পারি?

উদাহরণস্বরূপ, প্রদত্ত "StackOver" আমি দেখতে চাই

S
t
a
c
k
O
v
e
r

আমি মারতে নতুন তাই কোথা থেকে শুরু করব সে সম্পর্কে আমার কোনও ধারণা নেই।

উত্তর:


29

আমি ব্যবহার করব grep:

$ grep -o . <<<"StackOver"
S
t
a
c
k
O
v
e
r

বা sed:

$ sed 's/./&\n/g' <<<"StackOver"
S
t
a
c
k
O
v
e
r

এবং যদি শেষে খালি স্থানটি একটি সমস্যা হয়:

sed 's/\B/&\n/g' <<<"StackOver"

এটি সমস্ত জিএনইউ / লিনাক্স ধরে নিচ্ছে।


গ্রেপ -ও। <<< ¿¿¿.. - PATTERN এর জন্য অনুসন্ধান করা ঠিক আছে? এবং এটি আপনার আদেশ এখানে কি করে?
সিজন হাল্লাক

1
@ জিম্মিজ আমি <<< আসলে কী করে তাতে কোনও সহায়তা খুঁজে পাচ্ছি না! কোন সাহায্য?
সিজন হাল্লাক

3
@ সিজানহালাক এইটাকে বলা হয় Here string, গ্রোসো মোডো echo foo | ...মাত্র কম টাইপিংয়ের সমতুল্য । দেখুন tldp.org/LDP/abs/html/x17837.html
jimmij

1
@ সিজানহালাক এ পরিবর্তন .করুন \B(শব্দ সীমানায় মেলে না)।
জিম্মিজ

1
@ সিজানহাল্লাক - আপনি দ্বিতীয়টির sedমতো ড্রপ করতে পারেন:sed -et -e's/./\n&/g;//D'
মাইকজার্ভস

19

আপনি যদি পাঠ্যটিকে উল্লম্বভাবে মুদ্রণ করতে চান তবে আপনি অক্ষরের পরিবর্তে গ্রাফি ক্লাস্টারগুলিতে ভাঙতে চাইতে পারেন। উদাহরণস্বরূপ eতীব্র উচ্চারণ সহ একটি:

  • গ্রাফি ক্লাস্টারগুলির সাথে ( eএর তীব্র উচ্চারণের সাথে এক গ্রাফিয়াম ক্লাস্টার হবে):

    $ perl -CLAS -le 'for (@ARGV) {print for /\X/g}' $'Ste\u301phane'
    S
    t
    é
    p
    h
    a
    n
    e
    

    (বা grep -Po '\X'পিসিআরই সহায়তায় নির্মিত জিএনইউ গ্রেপ সহ)

  • অক্ষর সহ (এখানে জিএনইউ সহ grep):

    $ printf '%s\n' $'Ste\u301phane' | grep -o .
    S
    t
    e
    
    p
    h
    a
    n
    e
    
  • foldঅক্ষর ভাঙ্গার জন্য বোঝানো হয়েছে, তবে জিএনইউ foldমাল্টি-বাইট অক্ষরকে সমর্থন করে না, সুতরাং এটি পরিবর্তে বাইটগুলিতে ব্রেক করে:

    $ printf '%s\n' $'Ste\u301phane' | fold -w 1
    S
    t
    e
    �
    �
    p
    h
    a
    n
    e
    

উপর StackOver যা শুধুমাত্র ASCII অক্ষর নিয়ে গঠিত (তাই চরিত্র প্রতি এক বাইট, গ্রাফিম ক্লাস্টার প্রতি এক চরিত্র), সব তিনটি একই ফলাফল দেবে।


আমি অবাক হয়ে যাই grep -Poযা কেউ প্রত্যাশা করে না (যেমন grep -Pকরে)।
জিম্মিজ

@ জিম্মিজ, আপনার মানে কী? grep -Po .অক্ষর সন্ধান করে (এবং একটি নতুন লাইন চরিত্রের পরে সম্মিলিত তীব্র উচ্চারণটি অবৈধ), এবং grep -Po '\X'আমার জন্য গ্রাফেম ক্লাস্টারগুলি সন্ধান করে। এটা ঠিকমত কাজ জন্য (অথবা চেষ্টা, grep এবং / অথবা PCRE এর সর্বশেষ সংস্করণটি প্রয়োজন হতে পারে grep -Po '(*UTF8)\X')
Stéphane Chazelas

2
@ সিজানহালাক এগুলি সহায়ক হতে পারে: joelonsoftware.com/articles/Unicode.html , eev.ee/blog/2015/09/12/dark-corners-of-unicode
jpmc26

6

যদি আপনি perl6 আপনার বক্সে:

$ perl6 -e 'for @*ARGS -> $w { .say for $w.comb }' 'cường'       
c
ư
ờ
n
g

আপনার লোকাল নির্বিশেষে কাজ করুন।


6

অনেক awkসংস্করণ সহ

awk -F '' -v OFS='\n' '{$1=$1};1' <<<'StackOver'

গ্রেট! তবে আমার এনএডব্লিউকে ("ওয়ান ট্রু এডাব্লুকে") সংস্করণে এটি কার্যকর হয় না। তবে এই কৌতুক আছে: awk -v FS='' -v OFS='\n' '{$1=$1};1' (হতাশ যে যদি আরো পোর্টেবল যেহেতু -F ''ere উত্পাদ পারে: //)
eruve

4

নীচে জেনেরিক হবে:

$ awk -F '' \
   'BEGIN { RS = ""; OFS = "\n"} {for (i=1;i<=NF;i++) $i = $i; print }' <file_name>


4

যেহেতু আপনি বিশেষভাবে ব্যাশে উত্তর চেয়েছিলেন, খাঁটি বাশে এটি করার একটি উপায় এখানে রয়েছে:

while read -rn1; do echo "$REPLY" ; done <<< "StackOver"

নোট করুন যে এটি " এখানে নথি " শেষে নিউলাইনটি ধরবে । যদি আপনি এটি এড়াতে চান তবে তবুও ব্যাশ লুপের সাহায্যে অক্ষরগুলি পুনরাবৃত্তি করতে printfপারেন তবে নিউলাইনটি এড়াতে ব্যবহার করুন ।

printf StackOver | while read -rn1; do echo "$REPLY" ; done

4

এছাড়াও পাইথন 2 কমান্ড লাইন থেকে ব্যবহার করা যেতে পারে:

python <<< "for x in 'StackOver':
   print x"

বা:

echo "for x in 'StackOver':
    print x" | python

বা (1_CR দ্বারা মন্তব্য করা হয়েছে) পাইথন 3 এর সাথে :

python3 -c "print(*'StackOver',sep='\n')"

4

আপনি fold (1)কমান্ডটি ব্যবহার করতে পারেন । এটা তোলে অধিক কার্যকরী হয় grepএবং sed

$ time grep -o . <bigfile >/dev/null

real    0m3.868s
user    0m3.784s
sys     0m0.056s
$ time fold -b1 <bigfile >/dev/null

real    0m0.555s
user    0m0.528s
sys     0m0.016s
$

একটি উল্লেখযোগ্য পার্থক্য হ'ল ভাঁজ আউটপুটে খালি লাইনগুলি পুনরুত্পাদন করবে:

$ grep -o . <(printf "A\nB\n\nC\n\n\nD\n")
A
B
C
D
$ fold -b1 <(printf "A\nB\n\nC\n\n\nD\n")
A
B

C


D
$ 

3

আপনি মাল্টিবাইট অক্ষর যেমন পরিচালনা করতে পারেন:

<input \
dd cbs=1 obs=2 conv=unblock |
sed -e:c -e '/^.*$/!N;s/\n//;tc'

কোনটি চমত্কার কুশলী যখন আপনি সঙ্গেও কাজ করছি হতে পারে লাইভ এর কোন বাফারিং সেখানে এবং যত তাড়াতাড়ি এটি একটি চরিত্র ছাপা হয় কারণ ইনপুট পুরো


এনপি, আমরা লোকেল সম্পর্কে একটি নোট যোগ করা উচিত?
cuonglm

স্টাফেন চেজেলাস জবাবের মতো চরিত্রগুলিকে একত্রিত করার জন্য কাজ করে না, তবে যথাযথ সাধারণীকরণের সাথে এটি গুরুত্বপূর্ণ নয়।
কে 13 ই

@ কে - এটি অক্ষরগুলির সংমিশ্রনের জন্য কাজ করে যদি আপনি এটি চান - তবে sedস্ক্রিপ্টগুলি এর জন্য। আমি এখনই একটি লেখার সম্ভাবনা নেই - আমি খুব ঘুমিয়ে আছি। টার্মিনাল পড়ার সময় এটি সত্যিই দরকারী।
মাইকসার্ভ

@cuonglm - আপনি যদি চান। যদিও এটি একটি বুদ্ধিমান libc দেওয়া, কেবল লোকেলের জন্য কাজ করা উচিত।
মাইকসার্ভ

নোটটি ddমাল্টবাইটি অক্ষরগুলিকে ভেঙে দেবে, সুতরাং আউটপুটটি আর পাঠ্য হবে না সুতরাং সেডের আচরণটি পসিক্স অনুযায়ী নির্ধারিত হবে।
স্টাফেন চেজেলাস


1

ব্যাশে:

এটি যে কোনও পাঠ্য এবং কেবল ব্যাশ ইন্টার্নাল (কোনও বহিরাগত ইউটিলিটি বলে না) দিয়ে কাজ করে, সুতরাং খুব ছোট স্ট্রিংগুলিতে দ্রুত হওয়া উচিত।

str="Stéphane áàéèëêếe"

[[ $str =~ ${str//?/(.)} ]]
(set -- "${BASH_REMATCH[@]:1}"; IFS=$'\n'; echo "$*")

আউটপুট:

S
t
é
p
h
a
n
e

á
à
é
è
ë
ê
ế
e

যদি আইএফএস পরিবর্তন করা এবং অবস্থানগত পরামিতিগুলি পরিবর্তন করা ঠিক থাকে তবে আপনি সাব-শেল কলটি এড়াতে পারেন:

str="Stéphane áàéèëêếe"
[[ $str =~ ${str//?/(.)} ]]
set -- "${BASH_REMATCH[@]:1}"
IFS=$'\n'
echo "$*"

1
s=stackoverflow;

$ time echo $s | fold -w1                                                                                                                                          
s                                                                                                                                                                          
t                                                                                                                                                                          
a                                                                                                                                                                          
c                                                                                                                                                                          
k                                                                                                                                                                          
o                                                                                                                                                                          
v
e
r

real    0m0.014s
user    0m0.000s
sys     0m0.004s

আপডেটগুলি এখানে হ্যাকি | দ্রুততম | খাঁটিব্যাশবেসড উপায়!

$ time eval eval printf \'%s\\\\n\' \\\${s:\{0..$((${#s}-1))}:1}
s
t
a
c
k
o
v
e
r

real    0m0.001s
user    0m0.000s
sys     0m0.000s

আরও দুর্দান্ততার জন্য

function foldh () 
{ 
    if (($#)); then
        local s="$@";
        eval eval printf \'%s\\\\n\' \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
    else
        while read s; do
            eval eval printf \'%s\\\\n\' \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
        done;
    fi
}
function foldv () 
{ 
    if (($#)); then
        local s="$@";
        eval eval echo \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
    else
        while read s; do
            eval eval echo \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
        done;
    fi
}

এটি কি কখনও আলাদা ফলাফল দেবে fold -b1?
জিগ্লিগনাগা

যেহেতু প্রতিটি বাইটের প্রস্থ = 1 থাকে ফলাফল একই হবে!
জোনা

1
সুতরাং এটি কীভাবে আগের উত্তরটির সদৃশ নয় ?
জিগ্লিগনাগা

কারণ এটি বিভিন্ন অর্গিমেন্টের সাথে একই সেন্টিমিড দেখায় এবং এটি জেনে ভাল।
জোনা

1
read -a var <<< $(echo "$yourWordhere" | grep -o "." | tr '\n' ' ')

এটি আপনার কথাটি বিভক্ত করবে এবং এটিকে অ্যারে সংরক্ষণ করবে var


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