কোনও ফাইলের কোনও প্যাটার্নের কেবলমাত্র নবম উপস্থিতি কীভাবে প্রতিস্থাপন করবেন?


10

sedকমান্ড ব্যবহার করে ফাইলের স্ট্রিংয়ের তৃতীয় উপস্থিতিটি কীভাবে প্রতিস্থাপন করা যায় ।

উদাহরণ:

একমাত্র তৃতীয় সংঘটন পরিবর্তন isকরতে usফাইলে।

আমার ইনপুট ফাইলটিতে রয়েছে:

hai this is linux.
hai this is unix.
hai this is mac.
hai this is unchanged.

আমি আউটপুট আশা করছি:

hai this is linux.
hai thus is unix.
hai this is mac.
hai this is unchanged.

3
ইনপুট এবং আউটপুট একই।
হাউক লেগেইন

4
sedকাজের জন্য সঠিক সরঞ্জাম নয়।
চোরোবা

@ don_crissti আমি এটি ঠিক করেছি। ওপি বিন্যাসকরণ সরঞ্জামগুলি ব্যবহার করে নি (উপায় দ্বারা সুরেশকুমার, আপনার প্রশ্নগুলি সম্পাদনা করার জন্য এখানে সহায়তার জন্য দেখুন ) এবং পরের সম্পাদকরা যা চেয়েছিল তা ভুল বুঝেছিল।
টেরডন

উত্তর:


11

এটি দিয়ে অনেক সহজ কাজ করা হয়েছে perl

3 তম ঘটনাটি পরিবর্তন করতে :

perl -pe 's{is}{++$n == 3 ? "us" : $&}ge'

প্রতি 3 তম ঘটনা পরিবর্তন করতে :

perl -pe 's{is}{++$n % 3 ? $& : "us"}ge'

3

প্রতিস্থাপনের স্ট্রিং যখন প্রতি লাইনে কেবল একবার আসে, আপনি বিভিন্ন ইউটিলিটিগুলি একত্রিত করতে পারেন।
যখন ইনপুটটি "ইনপুট" ফাইলটিতে থাকে এবং আপনি "আমাদের" দ্বারা "" প্রতিস্থাপন করেন, আপনি ব্যবহার করতে পারেন

LINENR=$(cat input | grep -n " is " | head -3 | tail -1 | cut -d: -f1)
cat input | sed ${LINENR}' s/ is / us /'

প্রশ্নের উদাহরণে, isপ্রতি লাইনে একাধিক রয়েছে ।
টেরডন

আমি ভেবেছিলাম আপনি ফাঁক দিয়ে "ইজ" খুঁজছেন। আমি @ জিম্মিজ ব্যবহারের মতো টিআর কমান্ড দিয়ে আমার উত্তরটি সম্পাদনা করতে পারি, তবে আমার সমাধানটি তার থেকে অনেক নিকৃষ্টতর হয়ে উঠবে।
ওয়াল্টার এ 13

আমি প্রশ্নকারী নই :)। আমি একই জিনিস, যা কেন আমি আপনার উত্তর upvoted ছিল চিন্তা, কিন্তু যদি আপনি প্রশ্ন আসল সংস্করণে তাকান ( "আগে সম্পাদিত এক্স মিনিট" লিঙ্কটি ক্লিক করুন) দেখা হবে ওপি প্রত্যাশিত যে হয় মধ্যে এই এভাবে পরিবর্তন করা । যাইহোক, সেখানে বিড়ালের কোনও প্রয়োজন নেই।
টেরডন

2

নীচের স্ক্রিপ্টটি ( জিএনইউ sed সিনট্যাক্স ব্যবহার করে ) আউটপুট জন্য নয় ইনপ্লেস সম্পাদনার জন্য ব্যবহারযোগ্য কারণ এটি পছন্দসই প্রতিস্থাপনের পরে প্রিন্ট লাইনগুলি বন্ধ করে দেয়:

sed -i '/is/{: 1 ; /\(.*is\)\{3\}/!{N;b1} ; s/is/us/3 ; q}' text.file

আপনার মত চোরোবা সিদ্ধান্ত যদি আপনি উপরে পরিবর্তন করতে পারেন

sed '/is/{:1 ; /\(.*is\)\{3\}/!{N;b1} ; s/is/us/3 ; :2 ; n ; $!b2}' text.file

যা সমস্ত লাইনকে আউটপুট করে

অথবা আপনাকে সমস্ত লাইন প্যাটার্ন স্পেসে রেখে দিতে হবে (স্মৃতিতে তাই আকারের সীমাবদ্ধতার সাথে সাবধানতা অবলম্বন করুন) এবং প্রতিস্থাপন করতে হবে

sed ': 1 ; N ; $!b1 ; s/is/us/3 ' text.file

2

এর জন্য আপনি sedযদি নতুন লাইনগুলি অন্য কোনও অক্ষরে প্রতিস্থাপন করা হয় তবে এটি ব্যবহার করতে পারেন , যেমন:

tr '\n' '\000' | sed 's/is/us/3' | tr '\000' '\n'

এবং খাঁটি (জিএনইউ) এর সাথে একই sed:

sed ':a;N;$!ba;s/\n/\x0/g;s/is/us/3;s/\x0/\n/g'

( sedনিউলাইন প্রতিস্থাপনটি নির্লজ্জভাবে https://stackoverflow.com/a/1252191/4488514 থেকে চুরি হয়েছে )


আপনি যদি GNU sedনির্দিষ্ট সিনট্যাক্স ব্যবহার করতে চলেছেন তবে আপনি সম্ভবত এটি ব্যবহার করতে পারেন sed -z 's/is/us/3'
স্টাফেন চেজেলাস

@ StéphaneChazelas -z, কিছু ব্র্যান্ড নতুন বৈশিষ্ট্য থাকতে হবে আমার GNU sed version 4.2.1এই অপশনটি সম্পর্কে কিছু জানে না।
jimmij

1
4.2.2 (2012) এ যুক্ত হয়েছে। আপনার দ্বিতীয় সমাধানে, আপনাকে \x0পদক্ষেপ নিতে রূপান্তরের দরকার নেই ।
স্টাফেন চেজেলাস

সম্পাদনা সম্পর্কে দুঃখিত। আমি প্রশ্নের মূল সংস্করণটি দেখিনি এবং কেউ এটিকে ভুল বোঝে এবং ভুল লাইনটি সম্পাদনা করেছে। আমি আগের সংস্করণে ফিরে এসেছি।
টেরডন

1
p='[:punct:]' s='[:space:]'
sed -Ee'1!{/\n/!b' -e\}            \
     -e's/(\n*)(.*)/ \2 \1/'       \
     -e"s/is[$p]?[$s]/\n&/g"       \
     -e"s/([^$s])\n/\1/g;1G"       \
-e:c -e"s/\ni(.* )\n{3}/u\1/"      \
     -e"/\n$/!s/\n//g;/\ni/G"      \
     -e's//i/;//tc'                \
     -e's/^ (.*) /\1/;P;$d;N;D'

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

ফলশ্রুতিটি হ'ল এটি কোনও ফাইলের মধ্যে কেবল তৃতীয় ঘটনাটি সংশোধন করবে - এবং এটি প্রতি লাইনে গণনা বহন করবে। সুতরাং যদি কোনও ফাইল মনে হয়:

1. is is isis
2. is does

... এটি মুদ্রণ করবে ...

1. is is isis
2. us does

এটি প্রথমে প্রতিটি লাইনের মাথার এবং লেজগুলিতে একটি স্থান byুকিয়ে প্রান্তের কেসগুলি পরিচালনা করে। এটি শব্দের গণ্ডিগুলি নির্ধারণ করা আরও সহজ করে তোলে।

এরপরে এটি শূন্যের পূর্বে বা স্পেসের পরে একটি বিরামচিহ্ন অক্ষরের সমস্ত ঘটনার আগে isএকটি \nইললাইন সন্নিবেশ করে বৈধ এসের সন্ধান করবে is। এটি অন্য পাস করে এবং সমস্ত \nইওলাইনগুলি সরিয়ে দেয় যা অবিলম্বে কোনও স্থান নয় এমন চরিত্রের দ্বারা তৈরি। বামে পিছনে এই মার্কার ম্যাচ হবে is.এবং isকিন্তু thisবা ?is

এটি পরবর্তীকালে প্রতিটি চিহ্নিতকারীকে স্ট্রিংয়ের লেজের দিকে জড়ো করে - প্রতিটি \niলাইনের জন্য একটি লাইনে এটি \nস্ট্রিংয়ের লেজের সাথে একটি ewline সংযোজন করে এবং এর সাথে দুটি iবা এর সাথে প্রতিস্থাপন করে u। যদি \nস্ট্রিংয়ের লেজের পাশে এক সারিতে 3 টি ইলাইন থাকে তবে এটি ইউ ব্যবহার করে - অন্যথায় আমি। প্রথমবার আঃ ব্যবহার করা হয় এটিও সর্বশেষতম - প্রতিস্থাপনটি এমন একটি অসীম লুপ সেট করে যা নীচে ফোটে get line, print line, get line, print line,এবং এইভাবে।

প্রতিটি চেষ্টা লুপ চক্রের শেষে এটি সন্নিবেশ করা স্থানগুলি পরিষ্কার করে, প্যাটার্ন স্পেসে কেবলমাত্র প্রথম উপস্থিত নিউলাইন পর্যন্ত মুদ্রণ করে এবং আবার চলে যায়।

আমি lলুপটির মাথায় একটি uk কমান্ড যুক্ত করব :

l; s/\ni(.* )\n{9}/u\1/...

... এবং এই ইনপুটটির সাথে এটি কীভাবে কাজ করে তা একবার দেখুন:

hai this is linux.
hai this is unix.


hai this is mac.
hai this is unchanged is.

... সুতরাং এটি কি করে তা এখানে:

 hai this \nis linux. \n$        #behind the scenes
hai this is linux.               #actually printed
 hai this \nis unix. \n\n$       #it builds the marker string
hai this is unix.
  \n\n\n$                        #only for lines matching the

  \n\n\n$                        #pattern - and not otherwise.

 hai this \nis mac. \n\n\n$      #here's the match - 3 ises so far in file.
hai this us mac.                 #printed
hai this is unchanged is.        #no look here - this line is never evaled

এটি isপ্রতি লাইন প্রতি আরও এসএস দিয়ে আরও বোধগম্য করে তোলে :

nthword()(  p='[:punct:]' s='[:space:]'         
    sed -e '1!{/\n/!b' -e\}             \
        -e 's/\(\n*\)\(.*\)/ \2 \1/'    \
        -e "s/$1[$p]\{0,1\}[$s]/\n&/g"  \
        -e "s/\([^$s]\)\n/\1/g;1G;:c"   \
        -e "${dbg+l;}s/\n$1\(.* \)\n\{$3\}/$2\1/" \
        -e '/\n$/!s/\n//g;/\n'"$1/G"    \
        -e "s//$1/;//tc" -e 's/^ \(.*\) /\1/'     \
        -e 'P;$d;N;D'
)        

এটি কার্যত একই জিনিস তবে ডব্লিউ / পসিক্স বিআরই এবং মূল যুক্তি হ্যান্ডলিং।

 printf 'is is. is? this is%.0s\n' {1..4}  | nthword is us 12

... পায় ...

is is. is? this is
is is. is? this is
is is. is? this us
is is. is? this is

... এবং যদি আমি সক্ষম করি ${dbg}:

printf 'is is. is? this is%.0s\n' {1..4}  | 
dbg=1 nthword is us 12

... আমরা এটি পুনরাবৃত্তি দেখতে পারি ...

 \nis \nis. \nis? this \nis \n$
 is \nis. \nis? this \nis \n\n$
 is is. \nis? this \nis \n\n\n$
 is is. is? this \nis \n\n\n\n$
is is. is? this is
 \nis \nis. \nis? this \nis \n\n\n\n\n$
 is \nis. \nis? this \nis \n\n\n\n\n\n$
 is is. \nis? this \nis \n\n\n\n\n\n\n$
 is is. is? this \nis \n\n\n\n\n\n\n\n$
is is. is? this is
 \nis \nis. \nis? this \nis \n\n\n\n\n\n\n\n\n$
 is \nis. \nis? this \nis \n\n\n\n\n\n\n\n\n\n$
 is is. \nis? this \nis \n\n\n\n\n\n\n\n\n\n\n$
 is is. is? this \nis \n\n\n\n\n\n\n\n\n\n\n\n$
is is. is? this us
is is. is? this is

আপনি কি বুঝতে পারলেন যে আপনার উদাহরণটি "আইসিস" বলে?
flarn2006

@ flarn2006 - আমি নিশ্চিত যে এটি হ'ল।
মাইক্রজারভ

0

এখানে একটি যৌক্তিক সমাধান যা ব্যবহার করে sedএবং trএটি কাজ করার জন্য একটি স্ক্রিপ্টে অবশ্যই লেখা উচিত। নীচের কোডটি কমান্ডে উল্লিখিত শব্দের প্রতিটি তৃতীয় ঘটনা প্রতিস্থাপন করে sed। প্রতিস্থাপন i=3সঙ্গে i=nকোনো এই কাজটি করতে n

কোড:

# replace new lines with '^' character to get everything onto a single line
tr '\n' '^' < input.txt > output.txt

# count number of occurrences of the word to be replaced
num=`grep -o "apple" "output.txt" | wc -l`

# in successive iterations, replace the i + (n-1)th occurrence
n=3
i=3
while [ $i -le $num ]
do
    sed -i '' "s/apple/lemon/${i}" 'output.txt'
    i=$(( i + (n-1) ))
done

# replace the '^' back to new line character
tr '^' '\n' < output.txt > tmp && mv tmp output.txt


কেন এটি কাজ করে:

ধরা যাক পাঠ্য ফাইলটি a b b b b a c a d a b b b a b e b z b s b a b

  • যখন এন = 2: আমরা প্রতি দ্বিতীয় ঘটনাটি প্রতিস্থাপন করতে চাই b

    • a b b b b a c a d a b b b a b e b z b s b a b
      . . ^ . ^ . . . . . . ^ . . ^ . . . ^ . ^ . ^
    • প্রথমে আমরা ২ য় ঘটনা, তারপরে তৃতীয় ঘটনা, তারপরে ৪ র্থ, ৫ ম এবং আরও অনেক কিছু প্রতিস্থাপন করব। নিজের জন্য এটি দেখতে উপরের ক্রমিক হিসাবে গণনা করুন।
  • যখন এন = 3: আমরা প্রতি তৃতীয় ঘটনাটি প্রতিস্থাপন করতে চাই b

    • a b b b b a c a d a b b b a b e b z b s b a b
      . . . ^ . . . . . . . ^ . . . . ^ . . . . . ^
    • প্রথমে আমরা তৃতীয় ঘটনাটি প্রতিস্থাপন করি, তারপরে 5 তম, তার পরে 7 তম, 9 ম, 11 তম এবং আরও অনেক কিছু।
  • যখন এন = 4: আমরা প্রতি তৃতীয় ঘটনাটি প্রতিস্থাপন করতে চাই b

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