অস্থায়ী ফাইল ব্যবহার না করে আউটপুটটির প্রথম এন লাইনগুলি সরিয়ে দিন


11

মত একটি আউটপুট কল্পনা করুন

44444
55555
11111
22222
33333

আমি কীভাবে প্রথম এন লাইনগুলিকে ইয়াঙ্ক করতে পারি (উপরের উদাহরণে প্রথম দুটি) এবং সেগুলি শেষে যুক্ত করতে পারি, তবে টেম্প ফাইল ব্যবহার না করে (কেবলমাত্র পাইপ ব্যবহার করে)?

11111
22222
33333
44444
55555

এর পংক্তি বরাবর কিছু | sed -n '3,5p;1,2p'(যা স্পষ্টভাবে সেড হিসাবে কাজ করে না আদেশগুলির আদেশের যত্ন করে না)।


2
আমরা কেন একটি টেম্প ফাইল ব্যবহার করতে পারি না?
ব্রায়াম

উত্তর:


13

কেবল সেই রেখাগুলি হোল্ড বাফারে অনুলিপি করুন (তারপরে সেগুলি মুছুন) এবং শেষ লাইনে হোল্ড বাফার সামগ্রীটি প্যাটার্ন স্পেসে যুক্ত করুন:

some command | sed '1,NUMBER{           # in this range
H                                       # append line to hold space and
1h                                      # overwrite if it's the 1st line
d                                       # then delete the line
}
$G'                                     # on last line append hold buffer content

সঙ্গে gnu sedআপনি যেমন লিখতে পারে

some command | sed '1,NUMBER{H;1h;d;};$G'

এখানে 'ওল' এর সাথে আরেকটি উপায় রয়েছে ed(এটি পাঠ্য বাফারের rআউটপুটকে eড করে some commandএবং তারপরে লা mটির 1,NUMBERপরে লাইনগুলি ওভার করে $):

ed -s <<IN
r ! some command
1,NUMBERm$
,p
q
IN

দ্রষ্টব্য - যেমন উল্লেখ করা হয়েছে - আউটপুট NUMBER+1 কম লাইনে থাকলে এগুলি উভয়ই ব্যর্থ হবে । আরও দৃ approach় পদ্ধতির ( gnu sedসিনট্যাক্স) হবে:

some command | sed '1,NUMBER{H;1h;$!d;${g;q;};};$G'

এটি কেবলমাত্র সেই রেঞ্জের লাইনগুলি মুছে ফেলবে যতক্ষণ না তারা শেষ লাইন ( $!d) না হয় - অন্যথায় এটি হোল্ডার বাফার সামগ্রী ( g) এবং তারপরে qইউটগুলি (বর্তমান প্যাটার্ন স্পেস প্রিন্ট করার পরে) প্যাটার্ন স্পেসটিকে ওভাররাইট করে।


2
sed -e '1,NUMBER{H;1h;d;}' -e '$G'এছাড়াও portably কাজ করে (নোট যে কিছু sedবাস্তবায়নের হোল্ড মহাকাশে কয়েক কিলোবাইট চেয়ে বেশি রাখা যাবে না, তাই NUMBER টি অত্যন্ত বড় হতে পারে না সেখানে)
Stéphane Chazelas

@ স্টাফেনচাজেলাস - ইনপুটটির জন্য ধন্যবাদ - আমি নিশ্চিতভাবে জানতাম যে এটি পোর্টেবল - আমি সাধারণত প্রতি লাইন প্রতি একটি কমান্ড নিয়ে যাই - একাধিক এক্সপ্রেশন সিনট্যাক্স আমার কাছে সবসময় কিছুটা বিভ্রান্তিকর হয়ে থাকে যেমন প্যাসিক্স ডকস বলে যে "দ্য ডান ব্র্যাবস > হবে" << নিউলাইন> এর পূর্বে " সুতরাং তাদের মতে এটি হওয়া উচিত নয় sed -e '1,NUMBER{H;1h;d' -e'}' -e '$G'?
don_crissti

4
সাধারণত, একটি নতুন -eলাইন প্রতিস্থাপন করে। d;}এখনও পসিক্স নয় তবে বহনযোগ্য। এটি পরবর্তী পসিক্স স্পকে স্থির করা হবে। দেখুন অস্ট্রিংগ্রপবগ.টেন
স্টাফেন

2
@ ডন_ক্রিসটি ধন্যবাদ! এটি কেন কাজ করে তার একটি সংক্ষিপ্ত বিবরণ অন্তর্ভুক্ত করতে পারলে এটি দুর্দান্ত be (অবশ্যই আমি এটি সন্ধান করতে যাব, তবে এটি আরও মূল্যবান উত্তর দেবে))
পিটার উহানাক

আমার মাথায়, সম্পর্কে অপ্রয়োজনীয় জিনিসটি খোলার বন্ধনীটির তাত্ক্ষণিকের সাথে সাথে অর্ধিকোলন 1,NUMBER{H;1h;d;}না থাকে । এটি সুনোস ৪.১-এ কেবল একটি বাগ হতে পারে যার 20 বছর পরে যদিও এর কাজগুলি এখনও আমার আঙ্গুলগুলিতে তারযুক্ত। sed
zwol

11

একটি awkপদ্ধতির:

cmd | awk -v n=3 '
  NR <= n {head = head $0 "\n"; next}
  {print}
  END {printf "%s", head}'

@ Don_crissti এর sedপদ্ধতির উপর একটি সুবিধা হ'ল আউটপুটটিতে nলাইন বা তার চেয়ে কম থাকলে এটি এখনও কাজ করে (লাইনগুলি আউটপুট করে) ।


আপনি ওআরএসের \nসাথে হার্ডকোডযুক্ত প্রতিস্থাপন করতে চাইতে পারেন , যাতে এটি অন্যান্য রেকর্ড বিভাজকের সাথে কাজ করে (বলুন আপনি অনুচ্ছেদ ইত্যাদি ব্যবহার করতে চান)।
ফেডরকিই

6

আমার আছে xclipএবং এটি দিয়ে এটি করা যেতে পারে:

./a_command | xclip -in && xclip -o | tail -n +3 && xclip -o | head -n 2

এখানে এর বর্ণনা:

xclip - command line interface to X selections (clipboard)

NAME
       xclip - command line interface to X selections (clipboard)

SYNOPSIS
       xclip [OPTION] [FILE]...

DESCRIPTION
       Reads from standard in, or from one or more files, and makes the data available as an X selection for pasting into X applications. Prints current X selection to standard out.

       -i, -in
              read text into X selection from standard input or files (default)

       -o, -out
              prints the selection to standard out (generally for piping to a file or program)

3
এক্সক্লিপটির সৃজনশীল (ভুল) ব্যবহারের জন্য +1। উত্তরের একটি অ্যাক্সেসযোগ্য / চলমান এক্স সার্ভার দরকার।
জোফেল

3

একটি পার্ল উপায়:

perl -ne '$.<3?($f.=$_):print;}{print $f'

বা, একই জিনিস কম ক্রিপ্টিয়ালি লিখেছেন:

perl -ne 'if($.<3){ $f.=$_ } else{ print } END{print $f}'

উদাহরণ স্বরূপ:

$ cat file
44444
55555
11111
22222
33333

$ cat file | perl -ne '$.<3?($f.=$_):print;}{print $f'
11111
22222
33333
44444
55555

ব্যাখ্যা

  • -ne: ইনপুট ফাইল / স্ট্রিম লাইন লাইন পড়ুন এবং -eপ্রতিটি লাইনের দ্বারা প্রদত্ত স্ক্রিপ্ট প্রয়োগ করুন ।
  • $.<3: $.বর্তমান লাইন নম্বর, তাই 3আপনি যে লাইনের স্থানান্তর করতে চান তার সংখ্যায় পরিবর্তন করুন।
  • $.<3?($f.=$_):print;: এটি শর্তসাপেক্ষ অপারেটর, সাধারণ ফর্ম্যাটটি হ'ল condition ? case1 : case2, এটি case1যদি conditionসত্য হয় এবং case2এটি মিথ্যা হলে চলবে । এখানে, যদি বর্তমান লাইন সংখ্যা 3 এর চেয়ে কম হয়, তবে এটি চলতি রেখাটি ( $_) পরিবর্তনশীলটিতে সংযোজন করে $fএবং লাইন সংখ্যাটি 3 এর চেয়ে বেশি হলে এটি মুদ্রণ করে।
  • }{ print $f: }{পার্ল শর্টহ্যান্ড এর জন্য END{}। সমস্ত ইনপুট লাইনগুলি প্রক্রিয়া করার পরে এটি চলবে। এই মুহুর্তে, আমরা যে সমস্ত লাইনটি শিফট করতে চাইছি তা সংগ্রহ করব এবং আমরা একা ছেড়ে যেতে চাইলে সমস্ত মুদ্রণ করব, সুতরাং সংরক্ষণ করা লাইনগুলি মুদ্রণ করুন $f

1
আপনার গল্ফযুক্ত সংস্করণ সম্পর্কে কয়েকটি অক্ষর মুছে ফেলা যাবেperl -ne '$.<3?$f.=$_:print}{print $f
123

1

পসিক্স ব্যবহার করুন ex। হ্যাঁ, এটি ফাইল সম্পাদনা করার উদ্দেশ্যে তৈরি হয়েছে তবে এটি একটি পাইপলাইনে কাজ করবে।

printf %s\\n 111 222 333 444 555 | ex -sc '1,2m$|%p|q!' /dev/stdin

এটিতে পাইপলাইনের শুরু বা শেষের দিকে যেকোনও স্বেচ্ছাসেবক কমান্ড যুক্ত থাকতে পারে এবং একই কাজ করবে। আরও ভাল, উপস্থিতি দেওয়া /dev/stdin, এটি পসিক্স অনুগত।

(আমি জানি না যে /dev/stdinপসিক্সে নির্দিষ্ট করা আছে বা না, তবে আমি দেখতে পাচ্ছি এটি লিনাক্স এবং ম্যাক ওএস এক্সে উপস্থিত রয়েছে))

sedএর হোল্ড স্পেস ব্যবহার করার ক্ষেত্রে এটির পাঠযোগ্যতার সুবিধা রয়েছে - আপনি কেবল ex"এই রেখাগুলি শেষের দিকে সরান" বলুন এবং এটি তা করে। (বাকি কমান্ডগুলির অর্থ "বাফারটি প্রিন্ট করুন" এবং "প্রস্থান", যা মোটামুটি পাঠযোগ্য)

এনবি: exউপরোক্ত আদেশটি ইনপুট হিসাবে 2 টি লাইনের কম দিলে ব্যর্থ হবে।

আরও পড়া:


0

একটি সংক্ষিপ্ত pythonস্নিপেট:

#!/usr/bin/env python3
import sys
file_ = sys.argv[1]
lines = int(sys.argv[2])
with open(file_) as f:
    f = f.readlines()
    out = f[lines:] + f[:lines]
    print(''.join(out), end='')

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

উদাহরণ:

$ cat input.txt
44444
55555
11111
22222
33333

$ ./sw_lines.py input.txt 2
11111
22222
33333
44444
55555

$ ./sw_lines.py input.txt 4
33333
44444
55555
11111
22222


0

এখানে আরও একটি বিকল্প রয়েছে যার জন্য জিএনইউ প্রয়োজন sed:

(x=$(gsed -u 3q);cat;printf %s\\n "$x")

-uজিএনইউ sedআনফারড করে দেয় যাতে sedকমান্ডটি 3 টি লাইনের বেশি STDIN না খায়। কমান্ড প্রতিস্থাপন খালি লাইনগুলি সরিয়ে দেয়, যাতে তৃতীয়, তৃতীয় এবং দ্বিতীয়, বা তৃতীয়, দ্বিতীয় এবং প্রথম লাইনগুলি ফাঁকা থাকলে আউটপুট শেষে কমান্ডটি ফাঁকা লাইন অন্তর্ভুক্ত না করে।

আপনি এর মতো কিছু করতে পারেন:

tee >(sponge /dev/stdout|sed -u 3q)|sed 1,3d

sponge /dev/stdout|কমান্ড ছাড়া দীর্ঘ ইনপুট সঙ্গে ব্যর্থ হবে। এমনকি ইনপুটটি যেখানে একটি লাইনফিড রয়েছে বা তার সাথে প্রিন্ট করা হয় তারপরেও এটি sponge /dev/stdoutপ্রতিস্থাপন করা যায় tac|tac, যদিও এটি ইনপুটটির শেষে থেকে খালি লাইনগুলি সরিয়ে দেয়। উপরের কমান্ডটি প্রথম লাইনটি মুছে দেয় যখন ইনপুটটির রেখার সংখ্যা এক বা দুটি হয়।a\ncba\nb\nc\n(x=$(cat);printf %s\\n "$x")

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