সেড দিয়ে পাঠ্য ম্যানিপুলেশন


12

বর্তমানে, আমার কাছে একাধিক পাঠ্য ফাইল রয়েছে (অনেকগুলি লাইন সহ) এর মতো দেখায়:

565 0 10 12 23 18 17 25
564 1 7 12 13 16 18 40 29 15

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

0 565:10:1 565:12:1 565:23:1 565:18:1 565:17:1 565:25:1
1 564:7:1 564:12:1 564:13:1 564:16:1 564:18:1 564:40:1 564:29:1 564:15:1

উপরের শেড ব্যবহার করার কি কোনও উপায় আছে? নাকি পাইথন অবলম্বন করা দরকার?

উত্তর:


22

আপনি এটি সেড দিয়ে করতে পারেন, হ্যাঁ, তবে অন্যান্য সরঞ্জামগুলি সহজ। উদাহরণ স্বরূপ:

$ awk '{
        printf "%s ", $2; 
        for(i=3;i<=NF;i++){
            printf "%s:%s:1 ",$1,$(i) 
        }
        print ""
       }' file 
0 565:10:1 565:12:1 565:23:1 565:18:1 565:17:1 565:25:1 
1 564:7:1 564:12:1 564:13:1 564:16:1 564:18:1 564:40:1 564:29:1 564:15:1 

ব্যাখ্যা

awk প্রতিটি ক্ষেত্র সংরক্ষণ হোয়াইটস্পেস (ডিফল্ট অনুসারে) ইনপুট প্রতিটি লাইন বিভক্ত হবে $1, $2, $N। তাই:

  • printf "%s ", $2; ২ য় ক্ষেত্র এবং একটি স্থান অনুসরণযোগ্য স্থান মুদ্রণ করবে।
  • for(i=3;i<=NF;i++){ printf "%s:%s:1 ",$1,$(i) }: শেষ ক্ষেত্রের 3 ক্ষেত্রগুলিতে পুনরাবৃত্তি হবে (ক্ষেত্রের NFসংখ্যা) এবং তাদের প্রত্যেকের জন্য এটি 1 ম ক্ষেত্র, ক :, তারপরে বর্তমান ক্ষেত্র এবং ক মুদ্রণ করবে :1
  • print "" : এটি কেবল একটি চূড়ান্ত নিউলাইন প্রিন্ট করে।

বা পার্ল:

$ perl -ane 'print "$F[1] "; print "$F[0]:$_:1 " for @F[2..$#F]; print "\n"' file 
0 565:10:1 565:12:1 565:23:1 565:18:1 565:17:1 565:25:1 
1 564:7:1 564:12:1 564:13:1 564:16:1 564:18:1 564:40:1 564:29:1 564:15:1 

ব্যাখ্যা

-aতোলে perlমত আচরণ awkএবং হোয়াইটস্পেস তার ইনপুট বিভক্ত। এখানে ক্ষেত্রগুলি অ্যারেতে সংরক্ষণ করা হয় @F, যার অর্থ প্রথম ক্ষেত্রটি হবে $F[0], দ্বিতীয় $F[1]ইত্যাদি etc.

  • print "$F[1] " : 2 য় ক্ষেত্র প্রিন্ট করুন।
  • print "$F[0]:$_:1 " for @F[2..$#F];: শেষ ক্ষেত্রের 3 থেকে ক্ষেত্রগুলিতে পুনরাবৃত্তি করুন ( $#Fঅ্যারের উপাদানগুলির সংখ্যা এটি @Fতাই @F[2..$#F]অ্যারের শেষ পর্যন্ত 3 য় উপাদান থেকে শুরু করে একটি অ্যারের স্লাইস নেয়) এবং 1 ম ক্ষেত্র, ক :, তারপরে বর্তমান ক্ষেত্র এবং একটি মুদ্রণ করুন :1
  • print "\n" : এটি কেবল একটি চূড়ান্ত নিউলাইন প্রিন্ট করে।

12

এখানে একটি ভয়ঙ্কর sed উপায়!

$ sed -r 's/^([0-9]+) ([0-9]+) ([0-9]+)/\2 \1:\3:1/; :a s/([0-9]+)(:[0-9]+:1) ([0-9]+)( |$)/\1\2 \1:\3:1 /; t a; s/ $//' file
0 565:10:1 565:12:1 565:23:1 565:18:1 565:17:1 565:25:1 
1 564:7:1 564:12:1 564:13:1 564:16:1 564:18:1 564:40:1 564:29:1 564:15:1

আরও পঠনযোগ্য:

sed -r '
s/^([0-9]+) ([0-9]+) ([0-9]+)/\2 \1:\3:1/
:a 
s/([0-9]+)(:[0-9]+:1) ([0-9]+)( |$)/\1\2 \1:\3:1 /
t a
s/ $//'

মন্তব্য

  • -r আগে ব্যবহার করুন
  • s/old/new/oldসঙ্গে প্রতিস্থাপনnew
  • ^([0-9]+) লাইনের শুরুতে কিছু নম্বর সংরক্ষণ করুন
  • \1 প্রথম সংরক্ষিত প্যাটার্নের পিছনে উল্লেখ
  • :a স্ক্রিপ্টের এই বিভাগটি লেবেল করুন a
  • ( |$) হয় কোনও স্থান বা রেখার শেষ
  • t শেষ প্রতিস্থাপনটি সফল হয়েছিল কিনা পরীক্ষা করুন - এটি যদি হয় তবে পরবর্তী কমান্ডটি করুন
  • aলেবেলটি সন্ধান করুন :aএবং এটি আবার করুন
  • s/ $// চলার স্থানটি সরিয়ে ফেলুন

সুতরাং প্রথম অংশে কাঠামো যুক্ত করার পরে, আমরা বারবার কাঠামোর শেষ উদাহরণটি খুঁজে বার করে পরবর্তী সংখ্যায় প্রয়োগ করি ...

তবে আমি সম্মত হলাম অন্যান্য সরঞ্জামগুলি এটিকে আরও সহজ করে তোলে ...


আমি আপনার
এসড

: ডি আমাকে কিছুটা সময় নিয়েছিল রাভেক্সিনা - আমি মনে করি মুড়ু একটি ক্লিনার তৈরি করতে পারে
জান্না

5

জোর দিয়ে:

awk '{printf "%s ",$2; for (i=3; i<=NF; i++) printf $1":"$i":1 "; printf "\n"}' file

বা ব্যাশ সহ:

while read -r -a a; do                  # read line to array a
  printf "%s " ${a[1]}                  # print column #1
  for ((i=2;i<${#a[@]};i++)); do        # loop from column #2 to number of columns
    printf "%s " "${a[0]}:${a[$i]}:1"   # print content/values
  done
  echo                                  # print line break
done < file                             # read file from stdin

আউটপুট:

0 565: 10: 1 565: 12: 1 565: 23: 1 565: 18: 1 565: 17: 1 565: 25: 1 
1 564: 7: 1 564: 12: 1 564: 13: 1 564: 16: 1 564: 18: 1 564: 40: 1 564: 29: 1 564: 15: 1 

5

ঠিক আছে, আপনি এটি সেডে করতে পারেন, তবে অজগরটিও কাজ করে।

$ ./reformatfile.py  input.txt                                                                        
0 565:10:1 565:12:1 565:23:1 565:18:1 565:17:1 565:25:1
1 564:7:1 564:12:1 564:13:1 564:16:1 564:18:1 564:40:1 564:29:1 564:15:1

এর বিষয়বস্তু reformatfile.pyযেমন হয়:

#!/usr/bin/env python3
import sys

with open(sys.argv[1]) as fd:
    for line in fd:
        words = line.strip().split()
        pref = words[0]
        print(words[1],end=" ")
        new_words = [ ":".join([pref,i,"1"]) for i in words[2:] ]
        print(" ".join(new_words))

কিভাবে কাজ করে? আসলেই বিশেষ কিছু হচ্ছে না। আমরা পড়ার জন্য ফাইল হিসাবে প্রথম কমান্ড-লাইন আর্গুমেন্টটি খুলি এবং প্রতিটি লাইন "শব্দ" বা স্বতন্ত্র আইটেমগুলিতে বিচ্ছিন্ন করে এগিয়ে চলি। প্রথম শব্দগুলি prefপরিবর্তনশীল হয়ে যায় এবং আমরা স্টডআউট দ্বিতীয় (শব্দের [1]) আইটেমটি স্পেস দিয়ে শেষ করে মুদ্রণ করি। এরপরে আমরা .join()তালিকা বোধের মাধ্যমে "শব্দ" এর নতুন সেটটি তৈরি করি এবং প্রি, প্রতিটি শব্দ এবং স্ট্রিংয়ের অস্থায়ী তালিকায় ফাংশন করি "1"। চূড়ান্ত পদক্ষেপটি সেগুলি মুদ্রণ করা


4

সহ awk:

awk '{printf("%s ", $2); for(i=3; i<NF; i++) printf("%s:%s:1 ", $1, $i);\
          printf("%s:%s:1\n", $1, $NF)}' file.txt

এগুলি সমস্তই পছন্দসই বিন্যাসে স্থান-বিচ্ছিন্ন ক্ষেত্রগুলির বিন্যাসকরণের বিষয়ে:

  • printf("%s ", $2) একটি পিছনের স্থান সহ দ্বিতীয় ক্ষেত্র মুদ্রণ করে

  • for(i=3; i<NF; i++) printf("%s:%s:1 ", $1, $i) তৃতীয় থেকে দ্বিতীয় সর্বশেষ ক্ষেত্রগুলিতে পুনরাবৃত্তি হয় এবং পিছনের স্থান সহ ক্ষেত্রগুলি পছন্দসই বিন্যাসে (প্রথম ক্ষেত্র, তারপরে একটি কোলন, তারপরে বর্তমান ক্ষেত্র, তারপরে একটি কোলন, শেষ অবধি 1) মুদ্রণ করে

  • printf("%s:%s:1\n", $1, $NF) নিউলাইন দিয়ে শেষ ক্ষেত্রটি মুদ্রণ করে

উদাহরণ:

% cat file.txt
565 0 10 12 23 18 17 25
564 1 7 12 13 16 18 40 29 15

% awk '{printf("%s ", $2); for(i=3; i<NF; i++) printf("%s:%s:1 ", $1, $i); printf("%s:%s:1\n", $1, $NF)}' file.txt
0 565:10:1 565:12:1 565:23:1 565:18:1 565:17:1 565:25:1
1 564:7:1 564:12:1 564:13:1 564:16:1 564:18:1 564:40:1 564:29:1 564:15:1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.