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


102

আমি ব্যাশের মধ্যে অতিবাহিত সেকেন্ড দেখিয়ে একটি অগ্রগতি বার বাস্তবায়ন করতে চাই। এর জন্য, আমার পর্দায় প্রদর্শিত সর্বশেষ লাইনটি মুছে ফেলতে হবে (কমান্ড "ক্লিয়ার" সমস্ত স্ক্রিন মুছে ফেলবে, তবে আমার কেবল অগ্রগতি বারের লাইনটি মুছতে হবে এবং এটিকে নতুন তথ্য দিয়ে প্রতিস্থাপন করতে হবে)।

চূড়ান্ত ফলাফলটি দেখতে পাওয়া উচিত:

$ Elapsed time 5 seconds

তারপরে 10 সেকেন্ড পরে আমি এই বাক্যটি (পর্দার একই অবস্থানে) প্রতিস্থাপন করতে চাই:

$ Elapsed time 15 seconds

উত্তর:


117

car r সহ একটি গাড়ীর ফেরত প্রতিধ্বনিত করুন

seq 1 1000000 | while read i; do echo -en "\r$i"; done

মানুষের প্রতিধ্বনি থেকে:

-n     do not output the trailing newline
-e     enable interpretation of backslash escapes

\r     carriage return

19
for i in {1..100000}; do echo -en "\r$i"; doneসিক কলটি এড়াতে :-)
ডগলাস লিডার

এটি আমার যা প্রয়োজন ঠিক তা করে, ধন্যবাদ !! এবং সেক কমান্ডের ব্যবহার প্রকৃতপক্ষে পরিভাষাটি হিমশীতল করে :-)
ডিবাগার

11
যখন আপনি "আই ইন ইন $ (...)" বা "আই ইন ইন {1..N}" এর মতো জিনিসগুলি ব্যবহার করেন আপনি পুনরাবৃত্ত হওয়ার আগে সমস্ত উপাদান তৈরি করছেন, এটি বড় ইনপুটগুলির পক্ষে খুব অদক্ষ। আপনি পাইপের সুবিধা নিতে পারেন: "seq 1 100000 | i পড়ার সময়; কর ..." বা লুপের জন্য ব্যাশ সি-স্টাইল ব্যবহার করুন: "((i = 0; i ++)) এর জন্য করুন ..."
টোকল্যান্ড

ধন্যবাদ ডগলাস এবং টোকল্যান্ড - যদিও সিক্যুয়েন্স উত্পাদনটি সরাসরি প্রশ্নের অংশ না হলেও আমি টোকল্যান্ডের আরও দক্ষ পাইপে পরিবর্তিত হয়েছি
কেন

4
আমার ম্যাট্রিক্স প্রিন্টারটি আমার কাগজটিকে পুরোপুরি গোলমাল করছে। এটি একই কাগজের টুকরোতে জ্যামিং ডট রাখে যা আর নেই, এই প্রোগ্রামটি আর কতক্ষণ চলবে?
রব

188

গাড়ি নিজেই ফেরত কেবল কার্সারটিকে লাইনের শুরুতে সরিয়ে দেয়। এটি ঠিক আছে যদি প্রতিটি নতুন আউটপুট কমপক্ষে আগেরটির মতো দীর্ঘ হয় তবে নতুন লাইনটি যদি ছোট হয় তবে পূর্ববর্তী লাইনটি পুরোপুরি ওভাররাইট করা হবে না, যেমন:

$ echo -e "abcdefghijklmnopqrstuvwxyz\r0123456789"
0123456789klmnopqrstuvwxyz

নতুন পাঠ্যের জন্য লাইনটি সাফ করার জন্য আপনি এর \033[Kপরে যুক্ত করতে পারেন \r:

$ echo -e "abcdefghijklmnopqrstuvwxyz\r\033[K0123456789"
0123456789

http://en.wikedia.org/wiki/ANSI_escape_code


4
এটি আমার পরিবেশে সত্যই ভাল কাজ করে। সামঞ্জস্যতা কোন জ্ঞান?
আলেকজান্ডার ওলসন

21
বাশ-এ অন্তত এটির \e[Kপরিবর্তে ছোট করা যেতে পারে \033[K
ডেভ জেমস মিলার

দুর্দান্ত উত্তর! রুবি থেকে পুটস ব্যবহার করে পুরোপুরি কাজ করে। এখন আমার টুলকিটের একটি অংশ।
ফাতেমন

@ দ্য পিক্সেল বিকাশকারী: এটির উন্নতি করার চেষ্টা করার জন্য ধন্যবাদ, তবে আপনার সম্পাদনাটি ভুল ছিল। কার্সারটিকে লাইনের শুরুতে নিয়ে যেতে প্রথমে ফিরতে হবে, তারপরে কিলটি সেই কার্সার অবস্থান থেকে শেষ পর্যন্ত সমস্ত কিছু সাফ করে, পুরো লাইনটি ফাঁকা ছেড়ে যায়, যা উদ্দেশ্য। আপনি প্রতিটি নতুন লাইনের শুরুতে এগুলি কেনের উত্তরের অনুরূপ রেখেছিলেন, যাতে এটি খালি লাইনে লেখা থাকে।
ডেরেক ভাইট

4
শুধু রেকর্ডের জন্য, এক কি করতে পারেন \033[GIO \rসামনে \033[Kযদিও স্পষ্টত \rঅনেক সহজ। এছাড়াও invisible-island.net/xterm/ctlseqs/ctlseqs.html উইকিপিডিয়া চেয়ে অধিক বিবরণের দেয় এবং xterm ডেভেলপার থেকে।
জামাদগনি

20

ডেরিক ভাইটের উত্তর ততক্ষণ কাজ করে যতক্ষণ না লাইন দৈর্ঘ্য কখনই টার্মিনালের প্রস্থের বেশি হয় না। যদি এটি না হয় তবে নিম্নলিখিত কোডগুলি জাঙ্ক আউটপুটটিকে রোধ করবে:

প্রথমবার লাইনটি লেখার আগে করণীয়

tput sc

যা বর্তমান কার্সারের অবস্থান সংরক্ষণ করে। এখন যখনই আপনি আপনার লাইনটি মুদ্রণ করতে চান, ব্যবহার করুন

tput rc
tput ed
echo "your stuff here"

প্রথমে সংরক্ষিত কার্সার অবস্থানে ফিরে আসতে, তারপরে कर्सर থেকে নীচে স্ক্রীনটি সাফ করুন এবং শেষ পর্যন্ত আউটপুট লিখুন।


জঞ্জাল, এটি টার্মিনেটরে কিছুই করে না। সামঞ্জস্য সীমাবদ্ধতা আছে কিনা জানেন?
জেমি পেট

4
সাইগউইনের জন্য দ্রষ্টব্য: "টিপুট" ব্যবহার করতে আপনাকে প্যাকেজ "ncurses" ইনস্টল করতে হবে।
জ্যাক মিলার

এইচএম ... মনে হয় কাজ না করা যদি আরও একটি লাইন আউটপুটে থাকে। এটি কাজ করে না:tput sc # save cursor echo '' > sessions.log.json while [ 1 ]; do curl 'http://localhost/jolokia/read/*:type=Manager,*/activeSessions,maxActiveSessions' >> sessions.log.json echo '' >> sessions.log.json cat sessions.log.json | jq '.' tput rc;tput el # rc = restore cursor, el = erase to end of line sleep 1 done
Nux

@Nux এর tput edপরিবর্তে আপনার ব্যবহার করা উচিত tput el। @ উমের উদাহরণ ব্যবহৃত হয়েছে ed(আপনার মন্তব্য করার পরে তিনি সম্ভবত এটি স্থির করেছেন)।
স্টুডিক

এফওয়াইআই, এখানে টিপুট কমান্ডের তালিকা রয়েছে কল এবং কার্পার আন্দোলনের সাথে টিপুট
স্টুডিজ

13

3 033 পদ্ধতিটি আমার পক্ষে কাজ করে না। Method r পদ্ধতিটি কাজ করে তবে এটি আসলে কিছুই মুছে না, কেবল কার্সারটিকে লাইনের শুরুতে রাখে। সুতরাং যদি নতুন স্ট্রিংটি পুরানোটির চেয়ে কম হয় তবে আপনি লাইনের শেষে বাকী টেক্সটটি দেখতে পাবেন। শেষ দিকে টিপুটটি ছিল সবচেয়ে ভাল উপায়। এটিতে কার্সার স্টাফ ছাড়াও অন্যান্য ব্যবহার রয়েছে এবং এটি অনেকগুলি লিনাক্স এবং বিএসডি ডিস্ট্রোজে প্রাক ইনস্টলড আসে তাই এটি বেশিরভাগ ব্যাশ ব্যবহারকারীদের জন্য উপলব্ধ।

#/bin/bash
tput sc # save cursor
printf "Something that I made up for this string"
sleep 1
tput rc;tput el # rc = restore cursor, el = erase to end of line
printf "Another message for testing"
sleep 1
tput rc;tput el
printf "Yet another one"
sleep 1
tput rc;tput el

এখানে খেলতে এখানে একটি ছোট কাউন্টডাউন স্ক্রিপ্ট রয়েছে:

#!/bin/bash
timeout () {
    tput sc
    time=$1; while [ $time -ge 0 ]; do
        tput rc; tput el
        printf "$2" $time
        ((time--))
        sleep 1
    done
    tput rc; tput ed;
}

timeout 10 "Self-destructing in %s"

এটি সত্যিই পুরো লাইনটি সাফ করে দেয়, সমস্যাটি আমার জন্য খুব বেশি
পলক দেয়

5

অগ্রগতি আউটপুট একাধিক লাইন, বা স্ক্রিপ্টটি ইতিমধ্যে নতুন লাইন চরিত্রটি মুদ্রণ করেছে, আপনি লাইনগুলি এই জাতীয় কিছু দিয়ে ঝাঁপিয়ে দিতে পারেন:

printf "\033[5A"

যা কার্সারটিকে 5 লাইন উপরে লাফিয়ে তুলবে। তারপরে আপনি যা প্রয়োজন তার ওভাররাইট করতে পারেন।

যদি এটি কাজ না করে আপনি চেষ্টা করতে পারেন printf "\e[5A"বাecho -e "\033[5A" , যার একই প্রভাব হওয়া উচিত।

মূলত, এস্কেপ সিকোয়েন্সগুলির সাহায্যে আপনি পর্দার প্রায় সমস্ত কিছু নিয়ন্ত্রণ করতে পারেন।


এর পোর্টেবল সমতুল্য tput cuu 5যেখানে 5 টি সারিগুলির সংখ্যা ( cuuউপরে cudসরানো, নীচে সরানো)।
মাওলান

4

ক্যারেজ রিটার্ন চরিত্রটি ব্যবহার করুন:

echo -e "Foo\rBar" # Will print "Bar"

এই উত্তরটি সহজতম উপায়। আপনি এমনকি একই প্রভাবটি অর্জন করতে পারেন: মুদ্রণকারী "ফু ফু"
লী

1

গাড়ীর রিটার্ন রেখে এটি অর্জন করতে পারে \r

সহ কোডের একক লাইনে printf

for i in {10..1}; do printf "Counting down: $i\r" && sleep 1; done

বা সাথে echo -ne

for i in {10..1}; do echo -ne "Counting down: $i\r" && sleep 1; done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.