কমান্ড লাইন থেকে প্রতি দুটি লাইনকে কীভাবে একের সাথে একীভূত করা যায়?


151

নিম্নলিখিত ফর্ম্যাট সহ আমার কাছে একটি পাঠ্য ফাইল রয়েছে। প্রথম লাইনটি "KEY" এবং দ্বিতীয় লাইনটি "VALUE"।

KEY 4048:1736 string
3
KEY 0:1772 string
1
KEY 4192:1349 string
1
KEY 7329:2407 string
2
KEY 0:1774 string
1

আমি কী হিসাবে একই লাইনে মান প্রয়োজন। সুতরাং আউটপুট এর মত দেখতে হবে ...

KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1

এটা তোলে যদি আমি মত কিছু বিভেদক ব্যবহার করতে পারে ভাল হবে $বা ,:

KEY 4048:1736 string , 3

আমি কীভাবে দুটি লাইনে একত্রিত করব?


এটি করার জন্য অনেক উপায় আছে! আমি একটি কাজ করেছি সঙ্গে সামান্য বেঞ্চ pr, paste, awk, xargs, sedএবংpure bash ! ( xargsধীর, তুলনায় ধীর হয় ব্যাশ !)
এফ Hauri

উত্তর:


182

awk:

awk 'NR%2{printf "%s ",$0;next;}1' yourFile

দ্রষ্টব্য, আউটপুট শেষে একটি খালি লাইন আছে।

sed:

sed 'N;s/\n/ /' yourFile

রঙিন আউটপুট নিয়ে কাজ করে না। আমি এই প্রশ্নোত্তর সমস্ত কিছুর চেষ্টা করেছি এবং আউটপুট আনসি বর্ণযুক্ত হয়ে গেলে কিছুই কাজ করেনি। উবুন্টু 13.04
লিও গ্যালুচি

1
@ এলগালু: কারণ এএনএসআই রঙগুলি কেবল পালানোর চরিত্রের সমন্বয়। আপনার কাছে কী আছে তা দেখার জন্য এই জাতীয় আউটপুটটিতে একটি হেক্সিডিট করুন।
not2qubit

7
যদি এর printfমতো সম্প্রসারণের স্ট্রিংগুলির মধ্যে %sপাওয়া যায় তবে এই অজানা সমাধানটি ভাঙ্গতে পারে $0। সেই ব্যর্থতাটি এড়ানো যায়:'NR%2{printf "%s ",$0;next;}1'
ঘোটি

9
কারণ এটি গুগল করা সত্যিই কঠিন, কি করে 1 বন্ধ বন্ধনীটির অর্থ কী?
এরিকবওয়ার্ক

5
@ erikb85 এখানে আপনি যেতে stackoverflow.com/questions/24643240/...
Viraj

243

paste এই কাজের জন্য ভাল:

paste -d " "  - - < filename

10
আমি মনে করি না এটি সবচেয়ে ভাল সমাধান উপস্থাপন করা হয়েছে, সেড বা অজানা না ব্যবহার করেও। বিজয় সংখ্যক রেখার ইনপুটটিতে, কেন্টের বিশ্রী দ্রষ্টব্যটি চূড়ান্ত নতুনলাইনটি এড়িয়ে যায়, তার উপদ্রুত সমাধানটি চূড়ান্ত লাইনটি এঁকে দেওয়ার জন্য ছেড়ে যায় এবং আমার সমাধানটি শেষ লাইনে পুনরাবৃত্তি করে। pasteঅন্যদিকে, নিখুঁত আচরণ করে। +1 টি।
ঘোটি

8
আমি প্রায়শই ব্যবহার করি cutতবে সবসময় ভুলে যাই paste। এটি এই সমস্যার জন্য দোলা দেয়। আমার স্টিডিন থেকে সমস্ত লাইন একত্রিত করা দরকার এবং এটি সহজেই দিয়েছিলাম paste -sd ' ' -
ক্লিন্ট পাচল

4
সরল ও সুন্দর!
krlMLr

8
সুতরাং -স্টিডিনের অর্থ, সুতরাং স্টিডিনের paste - -কাছ থেকে পড়া, তারপর স্টিডিনের কাছ থেকে পড়ুন, আপনি যতটা চান আশা করতে পারেন তার মধ্যে অনেকগুলি স্ট্যাক করতে পারেন।
থারস্মমনার

1
হ্যাঁ, @ থারস্মমনার ... আমাকে প্রতি তিনটি লাইন একক লাইনে পেস্ট করতে হয়েছিল - এবং - এটি পুরোপুরি কার্যকর হয়েছিল perfectly
ড্যানিয়েল গোল্ডফারব 31'17

35

সেড, অ্যাজক, গ্রেপ এর বিকল্প:

xargs -n2 -d'\n'

আপনি যখন এন লাইনগুলিতে যোগ দিতে চান এবং আপনার কেবল স্থান সীমিত আউটপুট প্রয়োজন তখন এটি সবচেয়ে ভাল।

আমার আসল উত্তরটি ছিল xargs -n2যা রেখার চেয়ে শব্দের উপর পৃথক হয়। -dযে কোনও একক অক্ষর দ্বারা ইনপুট বিভক্ত করতে ব্যবহার করা যেতে পারে।


4
এটি একটি দুর্দান্ত পদ্ধতি, তবে এটি লাইনে নয় শব্দগুলিতে কাজ করে। এটি লাইনে কাজ করতে, যোগ করতে পারে-d '\n'
ডন হ্যাচ

2
বাহ, আমি একজন নিয়মিত xargsব্যবহারকারী কিন্তু এটি জানতাম না। দুর্দান্ত টিপ।
শ্রীধর সারনোবাত

1
আমি এটা ভালোবাসি. তাই পরিষ্কার।
আলেকজান্ডার গুও

28

ঝুলন্ত চেয়ে কুকুরকে মেরে ফেলার আরও অনেক উপায় আছে। [1]

awk '{key=$0; getline; print key ", " $0;}'

আপনার পছন্দসই ডিলিমিটারগুলি কোটের ভিতরে রাখুন।


তথ্যসূত্র:

  1. মূলত "বিড়ালের চামড়ার প্রচুর উপায়", এটি একটি পুরানো, সম্ভাব্য উত্সাহে প্রকাশে ফিরে আসে, যা পোষা প্রাণীর সাথেও কিছুই করার নেই।

আমি এই সমাধান ভালোবাসি।
luis.espinal

5
একটি বিড়ালের মালিক হিসাবে আমি এই জাতীয় কৌতুকের প্রশংসা করি না।
উইকটিসি 26

4
@ witkacy26, আপনার উদ্বেগের প্রতি সমন্বিত অভিব্যক্তি।
ঘোটি

আমি এই বুদ্ধিমান সমাধানটি পছন্দ করি তবে এটি কীভাবে কাজ করে তা আমি বুঝতে পারি না: এস
রুবেনডব

@ রুবেনডব - অ্যাডুক প্রতিটি ইনপুট লাইন পড়ে এবং এটি পরিবর্তনশীলে রাখে $0getlineকমান্ড এছাড়াও grabs ইনপুট এবং এটা স্থানে এর "পরবর্তী" লাইন $0। সুতরাং প্রথম বিবৃতিটি প্রথম লাইনটি ধরে ফেলে এবং মুদ্রণ কমান্ডটি ভেরিয়েবেলে কমাযুক্ত keyস্ট্রিং সহ যা সেভ করা হয়েছিল , সেই সাথে লাইনটি ব্যবহার করে আনা হয়েছিল getline। পরিস্কার? :)
ঘোটি

12

ব্যাশে আমার সমাধানটি এখানে:

while read line1; do read line2; echo "$line1, $line2"; done < data.txt

11

যদিও এটি মনে হয় যে পূর্ববর্তী সমাধানগুলি কাজ করবে, যদি নথিতে কোনও একক বিস্মৃতি ঘটে তবে আউটপুটটি টুকরো টুকরো হয়ে যায়। নীচে কিছুটা নিরাপদ।

sed -n '/KEY/{
N
s/\n/ /p
}' somefile.txt

3
এটি নিরাপদ কেন? কি করে /KEY/? pশেষে কি করে ?
স্টুয়ার্ট

/KEY/সঙ্গে সঙ্গতিপূর্ণ এর জন্য অনুসন্ধান KEYpকপি করে প্রিন্ট আউট স্থাপিত। এটি নিরাপদ কারণ এটি কেবল এটির সাথে লাইনে অপারেশন প্রয়োগ করে KEY
মিঙ্গুয়া

11

এখানে আরও একটি উপায় রয়েছে awk:

awk 'ORS=NR%2?FS:RS' file

$ cat file
KEY 4048:1736 string
3
KEY 0:1772 string
1
KEY 4192:1349 string
1
KEY 7329:2407 string
2
KEY 0:1774 string
1

$ awk 'ORS=NR%2?FS:RS' file
KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1

মন্তব্যগুলিতে এড মর্টন দ্বারা নির্দেশিত হিসাবে , সুরক্ষার জন্য ধনুর্বন্ধনী এবং পোর্টেন্সের জন্য প্যারেন্স যুক্ত করা ভাল।

awk '{ ORS = (NR%2 ? FS : RS) } 1' file

ORSআউটপুট রেকর্ড বিভাজক জন্য দাঁড়িয়েছে। আমরা এখানে NRযা করছি তা লাইন নম্বরটি সংরক্ষণ করে এমন একটি শর্ত পরীক্ষা করে । যদি এর মডুলোটি NRএকটি সত্য মান (> 0) হয় তবে আমরা আউটপুট ফিল্ড বিভাজকটিকে FS(ক্ষেত্র বিভাজক) এর মানতে সেট করে যা ডিফল্টরূপে স্থান হয়, অন্যথায় আমরা RS(রেকর্ড বিভাজক) এর মান নির্ধারণ করি যা নিউলাইন।

আপনি যদি ,বিভাজক হিসাবে যুক্ত করতে চান তবে নিম্নলিখিতগুলি ব্যবহার করুন:

awk '{ ORS = (NR%2 ? "," : RS) } 1' file

1
অবশ্যই সঠিক পদ্ধতিটি +1 করুন তবে আমি অবাক হই যে রেকর্ডটি মুদ্রণের ডিফল্ট ক্রিয়াকলাপটি শুরু করার জন্য কী অবস্থাটি মূল্যায়ন করা হচ্ছে। এটা কি এই নিয়োগ সফল হয়েছে? এটি সহজভাবে হয় ORSযে হিসাবে গণ্য করা হচ্ছে এবং trueযেহেতু ওআিএস একটি মান না না শূন্য বা নাল স্ট্রিং এবং সঠিকভাবে অনুমান যে এটা করা উচিত awks পায় একটি পরিবর্তে সাংখ্যিক তুলনা হুল? এটা কি অন্য কিছু? আমি সত্যিই নিশ্চিত নই এবং তাই আমি এটি লিখে রেখেছি awk '{ORS=(NR%2?FS:RS)}1' file। আমিও পোর্টেবিলিটি নিশ্চিত করতে ত্রৈমাসিক অভিব্যক্তিটিকে প্রথম বন্ধনীরূপে ফেলেছি।
এড মর্টন

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

7

"প্রাক্তন" হ'ল স্ক্রিপ্টযোগ্য লাইন সম্পাদক যা একই পরিবারে সেড, অ্যাজক, গ্রেপ ইত্যাদির মতো I আমি মনে করি এটি আপনি যা খুঁজছেন তা হতে পারে। অনেক আধুনিক ভি ক্লোন / উত্তরসূরিদের মধ্যে একটি ভিআই মোড থাকে।

 ex -c "%g/KEY/j" -c "wq" data.txt

এটি প্রতিটি লাইনের জন্য বলছে, যদি এটি "KEY" এর সাথে মেলে তবে নীচের লাইনের একটি জে ওন সঞ্চালন করুন । এই কমান্ডটি সম্পূর্ণ করার পরে (সমস্ত লাইনের বিপরীতে) একটি w rite এবং q uit জারি করুন ।


4

পার্ল যদি বিকল্প হয় তবে আপনি চেষ্টা করতে পারেন:

perl -0pe 's/(.*)\n(.*)\n/$1 $2\n/g' file.txt

না কি -0পার্কটি রেকর্ড বিভাজক সেট করতে বলে ( $/)নালায়, যাতে আমরা আমাদের মিলের প্যাটার্নে একাধিক লাইন বিস্তৃত করতে পারি practice
ম্যানপেজগুলি

4

2 টি লাইনের লাইন একত্রিত করতে আপনি এই জাতীয় উপায়ে ব্যবহার করতে পারেন:

awk '{ if (NR%2 != 0) line=$0; else {printf("%s %s\n", line, $0); line="";} } \
     END {if (length(line)) print line;}' flle

4

ভিএম ব্যবহার করে অন্য সমাধান (কেবলমাত্র রেফারেন্সের জন্য)।

সমাধান 1 :

ফাইলটি ভিএম-তে খুলুন vim filename, তারপরে কমান্ডটি কার্যকর করুন:% normal Jj

এই আদেশটি বুঝতে খুব সহজ:

  • %: সমস্ত লাইনের জন্য,
  • স্বাভাবিক: সাধারণ কমান্ড কার্যকর করুন
  • জেজে: জয়েন কমান্ড কার্যকর করুন, তারপরে নীচের লাইনে লাফ দিন

এর পরে, ফাইলটি সংরক্ষণ করুন এবং এর সাথে প্রস্থান করুন :wq

সমাধান 2 :

শেলের কমান্ডটি প্রয়োগ করুন vim -c ":% normal Jj" filename, তারপরে ফাইলটি সংরক্ষণ করুন এবং এর সাথে প্রস্থান করুন :wq


এছাড়াও norm!আরো জোরালো যে normalক্ষেত্রে Jremapped হয়েছে। ভিএম সমাধানের জন্য +1
কুইত্তজি

@ কিয়েটজি আমাকে তা শেখানোর জন্য ধন্যবাদ এটি জানতে পেরে খুব আনন্দিত। ^ _ ^
জেনসেন

3

আপনি নিম্নলিখিত vi কমান্ডটি ব্যবহার করতে পারেন:

:%g/.*/j

বা এমন কি :%g//jজন্য যেহেতু সব আপনি প্রয়োজন একটি ম্যাচ হয় যোগদানের নিষ্পন্ন করা হবে, এবং একটি নাল STRING এখনও একটি বৈধ Regex হয়।
ঘোটি

1
@ ঘোটি, ভিমে, যখন স্রেফ ব্যবহার করা হয় //, তার পরিবর্তে পূর্ববর্তী অনুসন্ধানের প্যাটার্ন ব্যবহার করা হবে। যদি পূর্বের কোনও প্যাটার্ন না থাকে তবে ভিম কেবল একটি ত্রুটির খবর দেয় এবং কিছুই করে না। জ্যামেডিয়ানের সমাধান সর্বদা কাজ করে।
জাজিংসিং ডেভিড ওয়াং

1
@ তজুনঘসিংডাভিডওয়ং - এটি ভিএম ব্যবহারকারীদের জন্য একটি ভাল পয়েন্টার। হ্যান্ডলি আমার জন্য, প্রশ্ন বা এই উত্তর ভিএম উল্লেখ করা হয়নি।
ঘোটি

3

গ্লেন জ্যাকম্যানের উত্তরের ব্যবহারের সাথে সামান্যতম প্রকরণটি ব্যবহার করে paste: যদি -dডিলিমিটার বিকল্পের মানটিতে একাধিক অক্ষর থাকে, pasteঅক্ষরগুলি একের পর এক করে করে থাকে এবং -sএকই ইনপুট ফাইলটি প্রক্রিয়াকরণের সময় অপশনগুলির সাথে একত্রিত হয় ।

এর অর্থ হ'ল আমরা যা করতে চাই সেগুলি পৃথককারী হিসাবে এবং পলায়ন ক্রম হিসাবে \nএকবারে দুটি লাইন একীভূত করতে ব্যবহার করতে পারি ।

কমা ব্যবহার করে:

$ paste -s -d ',\n' infile
KEY 4048:1736 string,3
KEY 0:1772 string,1
KEY 4192:1349 string,1
KEY 7329:2407 string,2
KEY 0:1774 string,1

এবং ডলার সাইন:

$ paste -s -d '$\n' infile
KEY 4048:1736 string$3
KEY 0:1772 string$1
KEY 4192:1349 string$1
KEY 7329:2407 string$2
KEY 0:1774 string$1

এটি যা করতে পারে না তা হ'ল একাধিক অক্ষর সমন্বিত একটি বিভাজক ব্যবহার করা।

বোনাস হিসাবে, যদি pasteপসিক্স অনুগত হয় তবে এটি ফাইলের শেষ লাইনটির নতুন লাইনটি পরিবর্তন করবে না, সুতরাং একটি ইনপুট ফাইলের মতো বিজোড় সংখ্যক লাইনের সাথে

KEY 4048:1736 string
3
KEY 0:1772 string

paste শেষ লাইনে পৃথকীকরণের চরিত্রটি গ্রহণ করবে না:

$ paste -s -d ',\n' infile
KEY 4048:1736 string,3
KEY 0:1772 string

1
nawk '$0 ~ /string$/ {printf "%s ",$0; getline; printf "%s\n", $0}' filename

এই হিসাবে পড়া

$0 ~ /string$/  ## matches any lines that end with the word string
printf          ## so print the first line without newline
getline         ## get the next line
printf "%s\n"   ## print the whole line and carriage return

1

যে ক্ষেত্রে আমাকে দুটি লাইন একত্রিত করার প্রয়োজন হয়েছিল (সহজ প্রক্রিয়াজাতকরণের জন্য), তবে নির্দিষ্ট তথ্যের কাছে থাকা ডেটাগুলিকে অনুমতি দেওয়া হয়েছে, আমি এটি দরকারী বলে মনে করেছি

data.txt

string1=x
string2=y
string3
string4
cat data.txt | nawk '$0 ~ /string1=/ { printf "%s ", $0; getline; printf "%s\n", $0; getline } { print }' > converted_data.txt

আউটপুট তারপর দেখতে:

converted_data.txt

string1=x string2=y
string3
string4

1

ভিএম ব্যবহার করে অন্য পদ্ধতি হ'ল:

:g/KEY/join

এটি joinশব্দটির সাথে যুক্ত সমস্ত লাইনে একটি (এর নীচের লাইনে) প্রয়োগ KEYকরে। ফলাফল:

KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1

0

সহজ উপায় এখানে:

  1. এমনকি লাইনগুলি সরান এবং কিছু অস্থায়ী ফাইল 1 এ লিখুন।
  2. বিজোড় লাইনগুলি সরান এবং কিছু অস্থায়ী ফাইল 2 এ লিখুন।
  3. -D দিয়ে পেস্ট কমান্ড ব্যবহার করে একটিতে দুটি ফাইল একত্রিত করুন (এর অর্থ স্পেস মুছুন)

sed '0~2d' file > 1 && sed '1~2d' file > 2 && paste -d " " 1 2

0
perl -0pE 's{^KEY.*?\K\s+(\d+)$}{ $1}msg;' data.txt > data_merged-lines.txt

-0লাইন বাই লাইন পড়ার পরিবর্তে পুরো ফাইলটি গবলস;
pEলুপের সাথে কোড মোড়ানো এবং আউটপুট প্রিন্ট করে, http://perldoc.perl.org/perlrun.html এ বিশদ দেখুন ;
^KEYলাইনের শুরুতে "কেইওয়াই" ম্যাচ করুন, তারপরে .*?ক্রমের আগে কোনও কিছুর ( ) লোভী মিল নেই

  1. \s+লাইন ব্রেক সহ যেকোন ধরণের এক বা একাধিক স্পেস ;
  2. এক বা একাধিক সংখ্যা (\d+)যা আমরা ক্যাপচার করি এবং পরে পুনরায় সন্নিবেশ করি $1;

লাইনের শেষে দ্বারা অনুসরণ $

\K সুবিধামত তার বিকল্প বাম দিক থেকে সবকিছু প্রতিস্থাপন থেকে বাদ দেয় { $1} প্রতিস্থাপন কেবল 1-2 ক্রম প্রতিস্থাপন করে, দেখুন http://perldoc.perl.org/perlre.html


0

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

#!/bin/bash
#
# join "The rest of the story" when the first line of each   story
# matches $PATTERN
# Nice for looking for specific changes in bart output
#

PATTERN='*:';
LINEOUT=""
while read line; do
    case $line in
        $PATTERN)
                echo ""
                echo $LINEOUT
                LINEOUT="$line"
                        ;;
        "")
                LINEOUT=""
                echo ""
                ;;

        *)      LINEOUT="$LINEOUT $line"
                ;;
    esac        
done

-1

নিম্নলিখিত লাইন চেষ্টা করুন:

while read line1; do read line2; echo "$line1 $line2"; done <old.txt>new_file

এর মধ্যে ডিলিমিটার রাখুন

"$line1 $line2";

যেমন যদি ডিলিমিটার হয় |তবে:

"$line1|$line2";

এই উত্তরটি হাই ভি এর উত্তরে প্রদত্ত নয় এমন কিছু যোগ করছে না যা আপনার 4 বছর আগে পোস্ট করা হয়েছিল।
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

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

-2

আপনি এটির xargsমতো ব্যবহার করতে পারেন :

xargs -a file

% বিড়াল> ফাইল abc% xargs- একটি ফাইল abc% আমার জন্য কাজ করে
আরএসজি

এটি কিছু করে, হ্যাঁ, তবে ওপি যা চেয়েছিল তা নয়। বিশেষত, এটি যতটা সম্ভব লাইনগুলিতে যোগদান করে। আপনি যা চান তা আসলে পেতে পারেন xargs -n 2তবে এই উত্তরটি মোটেই ব্যাখ্যা করে না।
ট্রিপলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.