শেষ এক্স উপস্থিতিগুলি বাদে একটি অক্ষর প্রতিস্থাপন করুন


9

আমার কাছে এমন একটি ফাইল রয়েছে যা এর মত দেখতে আইপিগুলির সাথে সংযুক্ত একটি হোস্ট নেম রয়েছে:

x-cluster-front-1 192.168.1.2
x-cluster-front-2 192.158.1.10
y-cluster-back-1 10.1.11.99
y-cluster-back-2 10.1.157.38
int.test.example.com 59.2.86.3
super.awesome.machine 123.234.15.6

আমি এটি দেখতে এটি দেখতে চাই:

x-cluster-front-1 192.168.1.2
x-cluster-front-2 192.158.1.10
y-cluster-back-1 10.1.11.99
y-cluster-back-2 10.1.157.38
int-test-example-com 59.2.86.3
super-awesome-machine 123.234.15.6

আমি কিভাবে প্রতিস্থাপন করতে পারেন। (ডটগুলি) প্রথম কলাম থেকে - (হাইফেন) দিয়ে দ্বিতীয় কলাম অনুসারে বাছাই করার সুবিধার্থে? আমি প্রথম স্থান অবধি বিন্দু প্রতিস্থাপনের জন্য সেড ব্যবহার করার কথা ভাবছিলাম, বা প্রতিটি বিন্দুর পরিবর্তে সর্বশেষ তিনটি প্রতিস্থাপন করছিলাম, কিন্তু রেজেেক্স এবং সেড বোঝার জন্য আমার সমস্যা হচ্ছে। আমি সাধারণ প্রতিস্থাপন সম্পাদন করতে পারি তবে এটি আমার মাথার উপরে!

এটি বৃহত্তর স্ক্রিপ্টের একটি অংশ যা আমি ব্যাশে লিখছি। আমি এই অংশে আটকে আছি।

উত্তর:


7

আপনি AWK ব্যবহার করতে পারেন

awk '{gsub(/-/,".",$1);print}' infile

ব্যাখ্যা

awkডিফল্টরূপে হোয়াইটস্পেসে একটি লাইন বিভাজন করে। সুতরাং, রেখার প্রথম কলামটি ( $1ইন- awkপিস) আপনি বিকল্পগুলি সম্পাদন করতে চান এমন এক হবে। এই উদ্দেশ্যে, আপনি ব্যবহার করতে পারেন:

 gsub(regex,replacement,string)

প্রয়োজনীয় প্রতিস্থাপন সম্পাদন করা।

নোট যেটি gsubকেবলমাত্র gawkএবং nawkতবে অনেকগুলি আধুনিক ডিস্ট্রো-তে সমর্থিত awkএটি একটি সফটলিঙ্ক gawk


1
আমাকে এতে মারধর করুন আমি মনে করি একটি ব্যাখ্যা সত্যিই প্রশ্নকারী এবং ভবিষ্যতের পাঠকদেরও উপকার করবে।
জোসেফ আর।

1
@JosephR। দুঃখিত, আমি ব্যাখ্যায় ভাল না তবে আমি চেষ্টা করেছি এবং আপডেট করেছি ..
রাহুল পাতিল

2
এর জন্য পসিক্স স্পেক awkভিত্তিক nawk, সুতরাং সমস্ত আধুনিক awkবাস্তবায়ন হওয়া উচিত gsub। সোলারিসে আপনার প্রয়োজন হতে পারে /usr/xpg4/bin/awkবা nawk
স্টাফেন চেজেলাস

@ রাহুলপাতিল যদি আপনি কিছু মনে করেন না, আমি কয়েকটি লাইন যুক্ত করেছি যা আমি মনে করি অন্যকে সাহায্য করবে।
জোসেফ আর।

@ জোসেফআর ধন্যবাদ .., এটি এখন নিখুঁত বলে মনে হচ্ছে .. :)
রাহুল পাতিল

6

যদি আপনাকে প্রথম ক্ষেত্রে বিকল্পগুলি করার দরকার হয়, তবে রাহুলের বিশ্রী সমাধানটি ব্যবহার করা সবচেয়ে ভাল তবে সাবধান থাকুন যে এটি ব্যবধানকে প্রভাবিত করতে পারে (ক্ষেত্রগুলি তাদের মধ্যে একটি একক জায়গার সাথে আবার লিখিত)।

পরিবর্তে এটি লিখে আপনি এড়াতে পারেন:

perl -pe 's|\S+|$&=~tr/./-/r|e' file

-pপতাকা মানে হলো "লাইন দ্বারা ইনপুট ফাইল লাইন পড়া এবং স্ক্রিপ্ট দেওয়া প্রয়োগের পরে প্রতিটি লাইনে প্রিন্ট -e"। তারপর, বিকল্প ( s|pattern|replacement|) অ-স্পেস অক্ষরের প্রথম ক্রম ( \S+) মিলেছে ধরণ (সঙ্গে $&) সমস্ত বদলে পর .সঙ্গে -। কৌতুক ব্যবহার করা s|||eযেখানে eঅপারেটর পরিবর্তে একটি অভিব্যক্তি মূল্যায়ন করবো। সুতরাং, আপনি আগেরটির tr/./-/( $&) এর ম্যাচ ( ) এর জন্য একটি প্রতিস্থাপন ( ) প্রয়োগ করতে পারেন s|||e

আপনি প্রতি প্রতিস্থাপন করার প্রয়োজন হলে .একটি সঙ্গে -গনুহ সঙ্গে গত 3 শেষ বেশী ছাড়া, sedএবং অভিমানী আপনি একটি আছে revকমান্ড প্রয়োগ করুন:

rev file | sed 's/\./-/4g' | rev

1
নোট করুন যে পার্ল দ্রবণটি 5.14 বা তার বেশি সংস্করণ ( /rকাজের জন্য) ধরেছে ।
জোসেফ আর।

3

শেড কাজের সহজতম সরঞ্জাম নয় - আরও ভাল সরঞ্জামের জন্য অন্যান্য উত্তর দেখুন - তবে এটি করা যেতে পারে।

প্রতিস্থাপন করতে .দ্বারা -শুধুমাত্র প্রথম স্থান, ব্যবহার করা sএকটি লুপ হবে।

sed -e '
  : a                     # Label "a" for the branching command
  s/^\([^ .]*\)\./\1-/    # If there is a "." before the first space, replace it by "-"
  t a                     # If the s command matched, branch to a
'

(দ্রষ্টব্য যে কয়েকটি সেড বাস্তবায়ন একই লাইনে মন্তব্যগুলিকে সমর্থন করে না G জিএনইউ সেড করে)

পরিবর্তে শেষ স্থান পর্যন্ত প্রতিস্থাপন সম্পাদন করতে:

sed -e '
  : a                     # Label "a" for the branching command
  s/\.\(.* \)/-\1/        # If there is a "." before the last space, replace it by "-"
  t a                     # If the s command matched, branch to a
'

অন্য কৌশলটি সেডের হোল্ড স্পেস ব্যবহার করে। আপনি যে বিটটি হোল্ড স্পেসে পরিবর্তন করতে চান না সেটিকে সংরক্ষণ করুন, আপনার কাজটি করুন, তারপরে হোল্ড স্পেসটি স্মরণ করুন। এখানে, আমি শেষ স্পেসে লাইনটি বিভক্ত করেছি এবং প্রথম অংশে ড্যাশ দ্বারা বিন্দুগুলি প্রতিস্থাপন করব।

sed -e '
  h           # Save the current line to the hold space
  s/.* / /    # Remove everything up to the last space
  x           # Swap the work space with the hold space
  s/[^ ]*$//  # Remove everything after the last space
  y/./-/      # Replace all "." by "-"
  G           # Append the content of the hold to the work space
  s/\n//      # Remove the newline introduced by G
'

2

যেহেতু রাহুল আপনাকে আপনার ব্যবহারের মামলার জবাব দিয়েছিল , তাই আমি ভেবেছিলাম যে আমি শিরোনামের সমস্যার উত্তর দিতে গিয়ে ছুরিকাঘাত করব: একটি রেজেক্সের শেষ x ঘটনাগুলি বাদে সমস্ত কিছু প্রতিস্থাপন:

perl -pe '
    $count = tr{.}{.}; # Count '.' on the current line
    $x = 3;
    next LINE if $count <= $x;
    while(s{\.}{-}){   # Substitute one '.' with a '-'
        last if ++$i == $count - $x # Quit the loop before the last x substitutions
    }
$i = 0
' your_file

উপরের কোড (পরীক্ষিত) ধরে নিচ্ছে না যে আপনার কাছে স্থান-বিভাজিত ক্ষেত্র রয়েছে। এটি সর্বশেষ 3 টি বিন্দু ছাড়া ড্যাশযুক্ত লাইনে সমস্ত বিন্দু প্রতিস্থাপন করবে। কোডটিকে 3কোডটি আপনার পছন্দ অনুসারে প্রতিস্থাপন করুন ।


2

আপনি এটির জন্য বিভিন্ন সরঞ্জাম ব্যবহার করতে পারেন। রাহুল পাতিল ইতিমধ্যে আপনাকে একটি উপহার দিয়েছেন gawkতাই এখানে আরও কয়েক জন রয়েছেন:

  • Perl

    perl -lane  '$F[0]=~s/\./-/g; print "@F"' file
    

    -aসুইচ কারণ হোয়াইটস্পেস এবং সংরক্ষণ অ্যারের মধ্যে ফলে ক্ষেত্র স্বয়ংক্রিয়ভাবে বিভক্ত ইনপুট লাইনে Perl @F। প্রথম ক্ষেত্র, তাই হতে হবে $F[0]যাতে আমরা প্রতিস্থাপন ( s///) এর সমস্ত ঘটনার .সঙ্গে -প্রথম মাঠে এবং তারপর সমগ্র অ্যারের মুদ্রণ করুন।

  • খোল

     while read -r a b; do printf "%s %s\n" "${a//./-}" "$b"; done < file 
    

    এখানে, লুপটি ফাইলটি পড়ে এবং স্বয়ংক্রিয়ভাবে সাদা স্থানগুলিতে বিভক্ত হয় his এটি দুটি ক্ষেত্র তৈরি করে $firstএবং $rest। কনস্ট্রাক্ট ${first//pattern/replacement}এর patternসাথে সমস্ত উপস্থিতি প্রতিস্থাপন করে replacement


+1 perlrun(1)আপনাকে বলবে যে -aএটি "অটোস্প্লিট মোড", আমি এটিকে " awkমোড" হিসাবে ভাবতে পছন্দ করি : ডি
জোসেফ আর।

2

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

while read -r host ip; do
    echo "$(sed 's/\./-/g' <<< "$host") $ip"
done < input_file

আপনার শেলের উপর নির্ভর করে আপনি সেড কমান্ডের পরিবর্তে $ {হোস্ট //./- use ব্যবহার করতে পারেন।


0
sed 's/\./-/' <file name>

gকমান্ডের শেষে ব্যবহার না করে আপনি এটি করতে পারেন… এটি কেবল প্যাটার্নের 1 ম ইভেন্টটিকে প্রতিস্থাপন করবে

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