একটি ব্যবহার করে একাধিক স্পেস সেড ব্যবহার করে কীভাবে ফেলা যায়?


69

sedএআইএক্স অন যা করছে তা আমার মনে হচ্ছে না। আমি IOSTAT এর আউটপুটে একক স্থান দিয়ে একাধিক স্পেস প্রতিস্থাপন করার চেষ্টা করছি:

# iostat
System configuration: lcpu=4 drives=8 paths=2 vdisks=0

tty:      tin         tout    avg-cpu: % user % sys % idle % iowait
          0.2         31.8                9.7   4.9   82.9      2.5

Disks:        % tm_act     Kbps      tps    Kb_read   Kb_wrtn
hdisk9           0.2      54.2       1.1   1073456960  436765896
hdisk7           0.2      54.1       1.1   1070600212  435678280
hdisk8           0.0       0.0       0.0          0         0
hdisk6           0.0       0.0       0.0          0         0
hdisk1           0.1       6.3       0.5   63344916  112429672
hdisk0           0.1       5.0       0.2   40967838  98574444
cd0              0.0       0.0       0.0          0         0
hdiskpower1      0.2     108.3       2.3   2144057172  872444176

# iostat | grep hdisk1
hdisk1           0.1       6.3       0.5   63345700  112431123

#iostat|grep "hdisk1"|sed -e"s/[ ]*/ /g"
 h d i s k 1 0 . 1 6 . 3 0 . 5 6 3 3 4 5 8 8 0 1 1 2 4 3 2 3 5 4

সেডকে পুরো গ্রুপ (/ জি) এর জন্য একক স্পেস (/ /) দিয়ে একাধিক স্পেস (/ [] * /) অনুসন্ধান এবং প্রতিস্থাপন করা উচিত ... তবে এটি কেবল তা করছে না ... এটি প্রতিটি চরিত্রকে ফাঁক করে দিচ্ছে।

আমি কি ভুল করছি? আমি জানি এটি সহজ কিছু হতে পারে ... এআইএক্স 5300-06

সম্পাদনা: আমার কাছে আরও একটি কম্পিউটার রয়েছে যার 10+ হার্ড ড্রাইভ রয়েছে। আমি এটিকে পর্যবেক্ষণের উদ্দেশ্যে অন্য প্রোগ্রামের প্যারামিটার হিসাবে ব্যবহার করছি।

আমার যে সমস্যাটি দেখা গিয়েছিল তা হ'ল "awk '{মুদ্রণ $ 5}' কাজ করেনি কারণ আমি দ্বিতীয় পর্যায়ে $ 1 ইত্যাদি ব্যবহার করছি এবং মুদ্রণ কমান্ডটিতে ত্রুটি দিয়েছি। আমি একটি গ্রেপ / সেড / কাট সংস্করণ খুঁজছিলাম কাজ দেখে মনে হচ্ছে:

iostat | grep "hdisk1 " | sed -e's/  */ /g' | cut -d" " -f 5

[] গুলি তখন "0 বা তার বেশি" ছিল যখন আমি ভেবেছিলাম যে তারা "কেবলমাত্র একটি" বোঝায়। বন্ধনী অপসারণ এটি কাজ করে। তিনটি খুব ভাল উত্তর সত্যিই দ্রুত "উত্তর" নির্বাচন করা কঠিন করে তোলে।

উত্তর:


52

grepঅপ্রয়োজনীয় ব্যবহার, sedএকই কাজ করতে পারে। সমস্যাটি *সেই ম্যাচের 0 টি ফাঁকা জায়গায় ব্যবহারের ক্ষেত্রেও রয়েছে, \+পরিবর্তে আপনাকে ব্যবহার করতে হবে:

iostat | sed -n '/hdisk1/s/ \+/ /gp'

যদি আপনার মেটাচার sedসমর্থন করে না \+, তবে করুন

iostat | sed -n '/hdisk1/s/  */ /gp'

এআইএক্স ++ সমর্থন করে না বলে মনে হচ্ছে, তবে []] এর অপসারণটি কৌশলটি করেছে বলে মনে হচ্ছে।
ওয়ার্নারসিডি

আমি সেড-এন সংস্করণটি ব্যবহার করার চেষ্টা করেছি ... যা ঘটে তা হয় আমার কাছে আরও একটি কম্পিউটার রয়েছে যার 10+ ড্রাইভ রয়েছে তাই এটি 1, 10, 11 ইত্যাদি শুরু করে ... আমি একটি স্থান / hdisk1 / যুক্ত করার চেষ্টা করেছি এবং এটি আমাকে দিয়েছে একটি "স্বীকৃত ফাংশন" নয়। যা কাজ বলে মনে হচ্ছে তা হল >> iostat | grep "hdisk1" | |
সেড

67

/[ ]*/শূন্য বা আরও বেশি জায়গার সাথে মেলে , তাই অক্ষরের মধ্যে ফাঁকা স্ট্রিং মেলে।

আপনি যদি "এক বা একাধিক স্পেস" মেলাতে চেষ্টা করছেন তবে এর একটি ব্যবহার করুন:

... | sed 's/  */ /g'
... | sed 's/ \{1,\}/ /g'
... | tr -s ' '

আহ ... [] এটি "alচ্ছিক" করে তোলে। এটি ব্যাখ্যা করে।
ওয়ার্নারসিডি

5
@ ওয়ার্নারসিডি, *এটিকে " alচ্ছিক " করে না। [ ]কেবলমাত্র এটিতে একটি অক্ষর (একটি স্থান) সহ অক্ষরের একটি তালিকা তৈরি করে। এটি *
কোয়ানটিফায়ার

আহ্ ... সুতরাং আরও নির্ভুল হওয়ার জন্য, এটি একটি একক স্থান / * / থেকে ডাবল স্পেসে পরিবর্তন করে যা তা তখন করেছিল। আমি পেয়েছি।
ওয়ার্নার সিডি

আমি এমন একটি প্যাটার্নটি অনুসন্ধান করার চেষ্টা করছিলাম যা কেবলমাত্র দ্বিগুণ স্পেস অনুসন্ধান করে এবং এটি দুর্দান্ত কাজ করেছে
minhas23

6
সহজ tr -s ' 'সমাধানের জন্য +1
অ্যান্ড্রেজ

12

আপনার *অপারেটরটি একটিতে পরিবর্তন করুন +। আপনি শূন্য বা আগের অক্ষরের সাথে আরও বেশি মিলছেন, যা প্রতিটি চরিত্রের সাথে মেলে কারণ সমস্ত কিছু যা স্থান নয় তা হ'ল ... উম ... শূন্যের উদাহরণ হ'ল স্থান। আপনার এক বা একাধিক ম্যাচ করা দরকার। আসলে দু'একটি বেশি ম্যাচ করা ভাল

বন্ধনীযুক্ত অক্ষর শ্রেণি একটি অক্ষরের সাথে মিলে যাওয়ার জন্যও অপ্রয়োজনীয়। আপনি কেবল ব্যবহার করতে পারেন:

s/  \+/ /g

... আপনি যদি ট্যাবগুলি বা অন্যান্য ধরণের স্পেসগুলি খুব বেশি মেলাতে না চান তবে অক্ষর শ্রেণিটি একটি ভাল ধারণা।


AIX সমর্থন করে না বলে মনে হচ্ছে +।
ওয়ার্নারসিডি

1
@ ওয়ার্ননারসিডি: তারপরে চেষ্টা করুন s/ */ /g(এটি তিনটি স্পেস সহ, মন্তব্য বিন্যাসকরণ সেগুলি ভেঙে যাচ্ছে)। তারকা অপারেটরটি পূর্বের চরিত্রটিকে alচ্ছিক করে তুলবে, সুতরাং এর সাথে যদি আপনি দুটি বা আরও বেশি কিছু মেলে আপনাকে প্রথমে দুটি নিজের সাথে মিলিত করতে হবে (দুটি স্পেস) তারপরে তৃতীয় এবং নীচের স্থানগুলি alচ্ছিক করতে একটি তৃতীয় স্থান এবং একটি তারকা যুক্ত করুন।
কালেব

3
@ ব্যবহারকারী: অজানা: আসলে আমি মোটে দুটি জিনিস মিশ্রিত করছি না, অন্য সবাই হ'ল: একটি একক স্থানকে একক স্থানের সাথে প্রতিস্থাপন করা অর্থহীন, আপনাকে কেবল কমপক্ষে দুটি ক্রমিক স্থান রয়েছে এমন ম্যাচে এই ক্রিয়াটি করা দরকার। দুটি ফাঁকা এবং একটি প্লাস বা তিনটি ফাঁকা এবং একটি তারা হ'ল প্রয়োজনীয়।
কালেব

@ ইউজারুননড: এটি এত বড় চুক্তি নয় যে এটি কেবলমাত্র প্রক্রিয়াজাতকরণের সামান্য সময় নষ্ট করে এবং এটি ম্যাচ কাউন্টারগুলির মতো জিনিস ফেলে দেয়।
কালেব

8

আপনি সর্বদা সর্বশেষ ঘটনাটি এর মতো কোনও কিছুর ক্রমটিতে মেলাতে পারেন:

s/\(sequence\)*/\1/

এবং তাই আপনি সঠিক পথে রয়েছেন, বরং স্থানটির সাথে ক্রমটি প্রতিস্থাপন করার পরিবর্তে - এটি একটি শেষ স্থান - একটি একক স্থানের সাথে প্রতিস্থাপন করুন। এই ভাবে যদি স্পেস একটা ক্রম হয় তারপর মিলেছে ক্রম একটি একক স্থান থেকে কমে যাবে, কিন্তু যদি নাল স্ট্রিং তারপর মিলেছে হয় নাল স্ট্রিং নিজেই দিয়ে প্রতিস্থাপিত করা হয় - এবং কোন ক্ষতি, কোন ফাউল। সুতরাং, উদাহরণস্বরূপ:

sed 's/\( \)*/\1/g' <<\IN                                    
# iostat
System configuration: lcpu=4 drives=8 paths=2 vdisks=0

tty:      tin         tout    avg-cpu: % user % sys % idle % iowait
          0.2         31.8                9.7   4.9   82.9      2.5

Disks:        % tm_act     Kbps      tps    Kb_read   Kb_wrtn
hdisk9           0.2      54.2       1.1   1073456960  436765896
hdisk7           0.2      54.1       1.1   1070600212  435678280
hdisk8           0.0       0.0       0.0          0         0
hdisk6           0.0       0.0       0.0          0         0
hdisk1           0.1       6.3       0.5   63344916  112429672
hdisk0           0.1       5.0       0.2   40967838  98574444
cd0              0.0       0.0       0.0          0         0
hdiskpower1      0.2     108.3       2.3   2144057172  872444176

# iostat | grep hdisk1
hdisk1           0.1       6.3       0.5   63345700  112431123

IN

আউটপুট

# iostat
System configuration: lcpu=4 drives=8 paths=2 vdisks=0

tty: tin tout avg-cpu: % user % sys % idle % iowait
 0.2 31.8 9.7 4.9 82.9 2.5

Disks: % tm_act Kbps tps Kb_read Kb_wrtn
hdisk9 0.2 54.2 1.1 1073456960 436765896
hdisk7 0.2 54.1 1.1 1070600212 435678280
hdisk8 0.0 0.0 0.0 0 0
hdisk6 0.0 0.0 0.0 0 0
hdisk1 0.1 6.3 0.5 63344916 112429672
hdisk0 0.1 5.0 0.2 40967838 98574444
cd0 0.0 0.0 0.0 0 0
hdiskpower1 0.2 108.3 2.3 2144057172 872444176

# iostat | grep hdisk1
hdisk1 0.1 6.3 0.5 63345700 112431123

যা যা বলেছিল, পুরোপুরি এই পরিস্থিতিতে রিজেক্সপস এড়ানো এবং এর পরিবর্তে করা আরও ভাল:

tr -s \  <infile

4
আসল উত্তরের সরলতার জন্য +1,iostat | tr -s \
ওয়াইল্ডকার্ড

'tr -s \' 'tr -s "" এর মতোই। আমাকে বুঝতে পেরেছিল যে স্থান "\" দিয়ে পালিয়ে স্ট্রিংয়ে আর্গুমেন্ট হিসাবে যেতে পারে। আমি দেখতে পাচ্ছি যে এটি শেল স্ক্রিপ্টগুলিতেও ব্যবহার করা যেতে পারে। শীতল আবেদন।
র্যান্ডমোস্ট্যান্সঅফলাইংথিং

5

লক্ষ্য করুন যে আপনি যা চেষ্টা করছেন তা করতে পারেন

iostat | grep "hdisk1 " | sed -e's/  */ /g' | cut -d" " -f 5

দ্বারা

iostat | while read disk tma kbps tps re wr; do [ "$disk" = "hdisk1" ] && echo "$re"; done

আপনি যদি পরে অন্যান্য ক্ষেত্রগুলিতে অ্যাক্সেস করার চেষ্টা করেন এবং / অথবা কোনও কিছু গণনা করে থাকেন তবে এটি বিশেষভাবে কার্যকর হতে পারে - এর মতো:

iostat | while read disk tma kbps tps re wr; do [ "$disk" = "hdisk1" ] && echo "$(( re/1024 )) Mb"; done

খুব সুন্দর. প্রথম সংস্করণ কাজ করে। আমার এআইএক্স বাক্সগুলি দ্বিতীয়টি পছন্দ করবে বলে মনে হচ্ছে না। তিনটি বাক্সের আউটপুট: "$ [পুনরায় / 1024] এমবি"। আমি যে পর্যবেক্ষণ সরঞ্জামটি ব্যবহার করছি তার প্রতিবেদনের জন্য রূপান্তর রয়েছে তাই এটি আমার পক্ষে "প্রয়োজনীয়" জিনিস নয়, তবে আমি এটি পছন্দ করি।
ওয়ার্নার সিডি

@ এঞ্জোটিব সংশোধন করার জন্য ধন্যবাদ while
rozcietrzewiacz

@ ওয়ার্ননার সিডি আহ, $[ .. ]এটি সম্ভবত বাশ এর সাম্প্রতিক সংস্করণগুলিতে উপলব্ধ (সম্ভবত zsh খুব)। আমি $(( .. ))পরিবর্তে আরও পোর্টেবল উত্তর আপডেট করেছি updated
রোজিট্রিজেভিয়াকজ

কৌতুকটি করেছে। আমি এটি সন্ধান করতে হবে। Snazzy।
ওয়ার্নার সিডি

0

একাধিক স্পেসকে একক স্থান, একটি ট্যাব বা অন্য কোনও স্ট্রিংয়ে রূপান্তর করতে আপনি নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করতে পারেন:

$ ls | compress_spaces.sh       # converts multiple spaces to one
$ ls | compress_spaces.sh TAB   # converts multiple spaces to a single tab character
$ ls | compress_spaces.sh TEST  # converts multiple spaces to the phrase TEST
$ compress_spaces.sh help       # show the help for this command

compress_spaces.sh

function show_help()
{
  IT=$(CAT <<EOF

  usage: {REPLACE_WITH}

  NOTE: If you pass in TAB, then multiple spaces are replaced with a TAB character

  no args -> multiple spaces replaced with a single space
  TAB     -> multiple spaces replaced with a single tab character
  TEST    -> multiple spaces replaced with the phrase "TEST"

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi

# Show help if we're not getting data from stdin
if [ -t 0 ]; then
  show_help
fi

REPLACE_WITH=${1:-' '}

if [ "$REPLACE_WITH" == "tab" ]
then
  REPLACE_WITH=$'\t'
fi
if [ "$REPLACE_WITH" == "TAB" ]
then
  REPLACE_WITH=$'\t'
fi

sed "s/ \{1,\}/$REPLACE_WITH/gp"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.