আমি কীভাবে ইউনিক্সের একটি পাঠ্য ফাইল থেকে পূর্বনির্ধারিত রেখাগুলি বের করতে পারি?


531

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

16224 এবং 16482 বলার লাইনের মধ্যবর্তী একটি ফাইল থেকে সমস্ত লাইন বের করতে এবং তারপরে সেগুলিকে একটি নতুন ফাইলে পুনর্নির্দেশ করার জন্য কি কেউ ইউনিক্স কমান্ড (বা কমান্ডের সিরিজ) জানেন?


যেহেতু আপনি বড় ফাইল উল্লেখ, আমি চেক করার পরামর্শ দিই মন্তব্য stackoverflow.com/questions/83329/...
sancho.s ReinstateMonicaCellio

উত্তর:


792
sed -n '16224,16482p;16483q' filename > newfile

থেকে sed ম্যানুয়াল :

p - প্যাটার্ন স্পেসটি প্রিন্ট করুন (স্ট্যান্ডার্ড আউটপুট থেকে)। এই কমান্ডটি সাধারণত -n কমান্ড-লাইন বিকল্পের সাথে একত্রে ব্যবহৃত হয়।

n - যদি অটো-প্রিন্ট অক্ষম না করা হয় তবে প্যাটার্ন স্পেসটি মুদ্রণ করুন, তবে নির্বিশেষে, পরবর্তী পংক্তির ইনপুট দিয়ে প্যাটার্ন স্পেসটি প্রতিস্থাপন করুন। যদি আরও ইনপুট না থাকে তবে সেড আরও কোনও কমান্ড প্রক্রিয়াকরণ ছাড়াই প্রস্থান করে।

q - আর sedকোনও কমান্ড বা ইনপুট প্রক্রিয়াজাত না করে প্রস্থান করুন। নোট করুন যে অটো-প্রিন্ট -n বিকল্পটি অক্ষম না করা থাকলে বর্তমান প্যাটার্নের স্থানটি মুদ্রিত হয়েছে।

এবং

একটি সেড স্ক্রিপ্টের ঠিকানাগুলি নিম্নলিখিত যে কোনও আকারে থাকতে পারে:

নম্বর একটি লাইন নম্বর নির্দিষ্ট করা ইনপুটটিতে কেবল সেই লাইনটির সাথে মিলবে।

কমা (,) দ্বারা পৃথক দুটি ঠিকানা নির্দিষ্ট করে একটি ঠিকানা সীমা নির্দিষ্ট করা যেতে পারে। একটি ঠিকানা পরিসীমা যেখানে প্রথম ঠিকানা মেলে সেখান থেকে শুরু হওয়া লাইনের সাথে মেলে এবং দ্বিতীয় ঠিকানার সাথে মিলিত হয় (সমেত) continues


3
এটি যদি আসল ফাইলটি পরিবর্তন করে তবে আমি আগ্রহী ছিলাম was আমি ঠিক সে ক্ষেত্রে এটির ব্যাক আপ রেখেছি এবং এটি প্রত্যাশার মতো এটি আসলটি পরিবর্তন করে নি।
অ্যান্ডি গ্রাফ

@AndyGroff। জায়গায় জায়গায় ফাইলটি পরিবর্তন করতে "-i" প্যারামিটার ব্যবহার করুন। অন্যথায় এটি ফাইলটি পরিবর্তন করবে না।
youri

175
যদি আমার মতো, আপনাকে খুব বড় একটি ফাইলে এটি করা দরকার হয়, আপনি যদি পরের লাইনে একটি ছাড়ার আদেশ যোগ করেন তবে এটি সহায়তা করে। তাহলে এটা sed -n '16224,16482p;16483q' filename। অন্যথায় সেড শেষ অবধি স্ক্যান করতে থাকবে (বা কমপক্ষে আমার সংস্করণটি করবে)।
wds

7
@ মাইলসআরআউট মানুষ জিজ্ঞাসা করছে "ডাউনটা কেন?" প্রায়শই, সম্ভবত আপনার অর্থ "কেউ যত্ন করে না"
মার্ক

1
@wds - আপনার মন্তব্যটি এমন উত্তরের দাবিদার যা শীর্ষে উঠে গেছে। এটি দিন এবং রাতের মধ্যে পার্থক্য তৈরি করতে পারে।
সানচো.এস পুনরায় ইনস্টল করুন মনিকাসেলিও

203
sed -n '16224,16482 p' orig-data-file > new-file

যেখানে 16224,16482 হ'ল শুরুর লাইন নম্বর এবং সমাপ্ত লাইন নম্বর, অন্তর্ভুক্ত। এটি 1-সূচকযুক্ত। -nইনপুট হিসাবে আউটপুট হিসাবে প্রতিধ্বনিকে দমন করে, যা আপনি পরিষ্কারভাবে চান না; সংখ্যাগুলি নিম্নলিখিত কমান্ডটি চালিত করতে রেখার পরিসীমা নির্দেশ করে; কমান্ড pপ্রাসঙ্গিক লাইন প্রিন্ট করে।


7
বড় ফাইলগুলিতে, উপরের কমান্ডটি পছন্দসই ব্যাপ্তিটি সন্ধান করার পরে পুরো ফাইলটি চালিয়ে যাবে। পরিসীমা আউটপুট হয়ে যাওয়ার পরে কি ফাইলের প্রক্রিয়াকরণ বন্ধ করার কোনও উপায় আছে?
গ্যারি

39
ওয়েল, থেকে উত্তর এখানে , মনে হয় যে পরিসর শেষে বাঁধন সঙ্গে সম্পন্ন করা যেতে পারে: sed -n '16224,16482p;16482q' orig-data-file > new-file
গ্যারি

5
কেন আপনি একটি অপ্রয়োজনীয় স্থান রাখবেন, এবং তারপরে উদ্ধৃতি দিতে হবে? (অবশ্যই, অপ্রয়োজনীয় সমস্যা তৈরি করা এবং সেগুলি সমাধান করা কম্পিউটার বিজ্ঞানের অর্ধেক অংশের মূল অংশ, তবে আমি সেই কারণটির সাথে বোঝাতে চাইছি ...)
কাজ

92

মাথা / লেজ ব্যবহার করে বেশ সহজ:

head -16482 in.sql | tail -258 > out.sql

সেড ব্যবহার:

sed -n '16482,16482p' in.sql > out.sql

কুট্টাল ব্যবহার:

awk 'NR>=10&&NR<=20' in.sql > out.sql

1
দ্বিতীয় এবং তৃতীয় বিকল্পগুলি ঠিক আছে, তবে প্রথমটি অনেকগুলি বিকল্পের চেয়ে ধীরে ধীরে কারণ এতে 2 টি কমান্ড ব্যবহৃত হয় যেখানে 1 টি পর্যাপ্ত। এটিতে সঠিক যুক্তি পেতে গণনা প্রয়োজন tail
জোনাথন লেফলার

3
প্রশ্নটির মতো একই লাইন নম্বরগুলি রাখার জন্য, sed -n 16224,16482p' in.sql >out.sqlawk 'NR>=16224&&NR<=16482' in.sql > out.sql
সেড

3
head -16482 in.sql | tail -$((16482-16224)) >out.sql
এটাও

1
মাথা এবং লেজযুক্ত প্রথমটি WAYYYY শেড সংস্করণের চেয়ে বড় ফাইলগুলিতে দ্রুত, এমনকি কি-অপশন যুক্ত হওয়ার সাথে। হেড-সংস্করণ তাত্ক্ষণিক এবং সেড সংস্করণ I Ctrl-C এক মিনিটের পরে ... ধন্যবাদ
মিয়াগি

2
tail -n +16224গণনা হ্রাস করতেও ব্যবহার করতে পারে
এসওএফই

35

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

:16224,16482w!/tmp/some-file

বিকল্পভাবে:

cat file | head -n 16482 | tail -n 258

সম্পাদনা করুন: - কেবল ব্যাখ্যা যুক্ত করতে, আপনি প্রথম 16482 লাইন প্রদর্শন করতে হেড -n 16482 ব্যবহার করেন তারপরে প্রথম আউটপুট থেকে শেষ 258 লাইন পেতে লেজ -n 258 ব্যবহার করুন ।


2
এবং vi এর পরিবর্তে আপনি প্রাক্তনটি ব্যবহার করতে পারেন, এটি vi মাইনাস ইন্টারেক্টিভ কনসোল স্টাফ।
টাদিউস এ। কাদুউবস্কি

1
আপনার catআদেশের দরকার নেই ; headসরাসরি একটি ফাইল পড়তে পারেন। এটি অনেক বিকল্পের চেয়ে ধীর কারণ এটি 2 (3 হিসাবে দেখানো হয়েছে) কমান্ড ব্যবহার করে যেখানে 1 টি যথেষ্ট।
জোনাথন লেফলার

1
@ জোনাথনলফলার আপনি যথেষ্ট ভুল করেছেন এটি নির্লজ্জভাবে দ্রুত। আমি কয়েক সেকেন্ডে (ছাড়াই cat) 500k লাইন সহ 2G ফাইল থেকে 200k লাইন, প্রায় 1G, বের করি । অন্যান্য সমাধানগুলির জন্য কমপক্ষে কয়েক মিনিট প্রয়োজন। এছাড়াও জিএনইউতে দ্রুততম পার্থক্য বলে মনে হচ্ছে tail -n +XXX filename | head XXX
আন্তোনিস ক্রিস্টোফাইডস

28

এর সাথে আরও একটি পদ্ধতি রয়েছে awk:

awk 'NR==16224, NR==16482' file

ফাইলটি বিশাল exitআকারের হলে শেষ কাঙ্ক্ষিত লাইনটি পড়ার পরে ভাল হয় । এইভাবে, এটি অকারণে নিম্নলিখিত লাইনগুলি পড়বে না:

awk 'NR==16224, NR==16482-1; NR==16482 {print; exit}' file

awk 'NR==16224, NR==16482; NR==16482 {exit}' file

2
1+ ব্যবহার করে রানটাইম এবং সংস্থান সংরক্ষণ করার জন্য print; exit। ধন্যবাদ!
বার্নি রিটার

২ য় উদাহরণের কিছুটা সরলকরণ:awk 'NR==16224, NR==16482; NR==16482 {exit}' file
রবিন এ মেইড

এটি উজ্জ্বল, ধন্যবাদ @ রবিনএ.মিয়েড! আমি পোস্টে আপনার ধারণাটি সম্পাদনা করেছি
ফেডোরকুই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'


9
 # print section of file based on line numbers
 sed -n '16224 ,16482p'               # method 1
 sed '16224,16482!d'                 # method 2

6
cat dump.txt | head -16224 | tail -258

কৌতুক করা উচিত। এই পদ্ধতির খারাপ দিকটি হ'ল লেজের পক্ষে যুক্তি নির্ধারণ করার জন্য এবং আপনি শেষের রেখাটি অন্তর্ভুক্ত করার জন্য 'এর মধ্যে' চান কিনা তা জবাবদিহি করতে আপনাকে পাটিগণিত করতে হবে।


4
আপনার catআদেশের দরকার নেই ; headসরাসরি একটি ফাইল পড়তে পারেন। এটি অনেক বিকল্পের চেয়ে ধীর কারণ এটি 2 (3 হিসাবে দেখানো হয়েছে) কমান্ড ব্যবহার করে যেখানে 1 টি যথেষ্ট।
জোনাথন লেফলার

@ জোনাথনলফলার এই উত্তরটি পড়া এবং মনে রাখা সবচেয়ে সহজ। আপনি যদি পারফরম্যান্সের বিষয়ে সত্যই যত্নশীল হন তবে আপনি প্রথমে কোনও শেল ব্যবহার করবেন না। নির্দিষ্ট সরঞ্জামগুলি একটি নির্দিষ্ট কাজের জন্য নিজেকে উত্সর্গ করতে দেওয়া ভাল অনুশীলন। তদতিরিক্ত, "পাটিগণিত" ব্যবহার করে সমাধান করা যেতে পারে | tail -$((16482 - 16224))
ইয়েতি

6

বক্সক্সারের কাঁধে দাঁড়িয়ে, আমি এটি পছন্দ করি:

sed -n '<first line>,$p;<last line>q' input

যেমন

sed -n '16224,$p;16482q' input

এর $অর্থ "শেষ লাইন", সুতরাং প্রথম কমান্ডটি sedলাইন দিয়ে শুরু করে সমস্ত লাইন প্রিন্ট করে 16224এবং দ্বিতীয় কমান্ড প্রিন্টিং লাইনের পরেsed প্রস্থান করে । ( বক্সরসার সমাধানে -আরঞ্জের জন্য যোগ করা প্রয়োজনীয় বলে মনে হয় না))164281q

আমি এই বৈকল্পিকটি পছন্দ করি কারণ আমার শেষবারের লাইন নম্বরটি দু'বার উল্লেখ করার দরকার নেই। এবং আমি পরিমাপ করেছি যে ব্যবহারের $পারফরম্যান্সে ক্ষতিকারক প্রভাব নেই।



3

দ্রুত এবং ময়লা:

head -16428 < file.in | tail -259 > file.out

সম্ভবত এটি করার সর্বোত্তম উপায় নয় তবে এটি কাজ করা উচিত।

বিটিডাব্লু: 259 = 16482-16224 + 1।


এটি অনেক বিকল্পের চেয়ে ধীর কারণ এটি 2 কমান্ড ব্যবহার করে যেখানে 1 পর্যাপ্ত।
জোনাথন লেফলার

3

আমি স্প্লিটার নামে একটি হাস্কেল প্রোগ্রাম লিখেছিলাম যা ঠিক এটি করে: আমার প্রকাশিত ব্লগ পোস্টের মাধ্যমে পড়ুন

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

$ cat somefile | splitter 16224-16482

এবং এটি যে এটি আছে। এটি ইনস্টল করার জন্য আপনার হাস্কেলের প্রয়োজন হবে। শুধু:

$ cabal install splitter

এবং আপনি সম্পন্ন হয়েছে। আমি আশা করি আপনি এই প্রোগ্রামটি দরকারী মনে করেন।


না splitterশুধুমাত্র স্ট্যান্ডার্ড ইনপুট থেকে পড়া? এক অর্থে, এটি কিছু যায় আসে না; catকমান্ড তা করে বা না প্রযোজন নেই। হয় ব্যবহার করুন splitter 16224-16482 < somefileবা (যদি এটি ফাইলের নাম আর্গুমেন্ট নেয়) splitter 16224-16482 somefile
জোনাথন লেফলার

3

এমনকি আমরা কমান্ড লাইনে যাচাই করতে এটি করতে পারি:

cat filename|sed 'n1,n2!d' > abc.txt

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

cat foo.pl|sed '100,200!d' > abc.txt

6
catএগুলির একটিতেও আপনার কমান্ডের দরকার নেই ; sedনিজে থেকে ফাইল পড়তে পুরোপুরি সক্ষম, বা আপনি কোনও ফাইল থেকে স্ট্যান্ডার্ড ইনপুট পুনর্নির্দেশ করতে পারেন।
জনাথন লেফলার


2

আমি মাথা / লেজ ট্রিক পোস্ট করতে চলেছি, তবে আসলে আমি সম্ভবত ইম্যাকগুলি সরিয়ে ফেলব। ;-)

  1. esc- xগোটো-লাইনret গোটো 16224
  2. চিহ্ন ( ctrl-space )
  3. esc- xগোটো-লাইনret গোটো 16482
  4. esc-w

নতুন আউটপুট ফাইল খুলুন, ctl-y সেভ

আমাকে দেখতে দিন কি ঘটছে।


4
ইমাক্স আমার অভিজ্ঞতায় খুব বড় ফাইলগুলিতে খুব ভাল অভিনয় করে না।
গ্রেগ ম্যাটিস

আপনি কি এটি স্ক্রিপ্টেড ক্রিয়া হিসাবে চালাতে পারেন, বা এটি কেবল একটি ইন্টারেক্টিভ বিকল্প?
জোনাথন লেফলার

2

আমি ব্যবহার করব:

awk 'FNR >= 16224 && FNR <= 16482' my_file > extracted.txt

এফএনআর ফাইল থেকে পড়া পংক্তির রেকর্ড (লাইন) নম্বর ধারণ করে।


2

আমি একটি পরিবর্তনশীল ব্যবহার করে স্ক্রিপ্ট থেকে একই জিনিসটি করতে চেয়েছিলাম এবং ভেরিয়েবলের নাম পি থেকে পৃথক করতে around ভেরিয়েবলের চারপাশে উদ্ধৃতি রেখে এটি অর্জন করেছি:

sed -n "$first","$count"p imagelist.txt >"$imageblock"

আমি একটি তালিকা আলাদা ফোল্ডারে বিভক্ত করতে চেয়েছিলাম এবং প্রাথমিক প্রশ্নটি খুঁজে পেয়ে একটি দরকারী পদক্ষেপের উত্তর দিতে চাই। (স্পোর্ট কমান্ডটি পুরাতন কোডে আমাকে পুরাতন ওএসের বিকল্প নয়)।


1

আমি একটি ছোট বাশ স্ক্রিপ্ট লিখেছি যা আপনি আপনার কমান্ড লাইন থেকে চালাতে পারেন, আপনি যতক্ষণ না আপনার PATH এর ডিরেক্টরি অন্তর্ভুক্ত করার জন্য আপডেট করেন (বা আপনি এটি ইতিমধ্যে PATH- এ অন্তর্ভুক্ত কোনও ডিরেক্টরিতে রাখতে পারেন)।

ব্যবহার: $ চিমটি ফাইলের নাম শুরুর লাইন শেষ-লাইন

#!/bin/bash
# Display line number ranges of a file to the terminal.
# Usage: $ pinch filename start-line end-line
# By Evan J. Coon

FILENAME=$1
START=$2
END=$3

ERROR="[PINCH ERROR]"

# Check that the number of arguments is 3
if [ $# -lt 3 ]; then
    echo "$ERROR Need three arguments: Filename Start-line End-line"
    exit 1
fi

# Check that the file exists.
if [ ! -f "$FILENAME" ]; then
    echo -e "$ERROR File does not exist. \n\t$FILENAME"
    exit 1
fi

# Check that start-line is not greater than end-line
if [ "$START" -gt "$END" ]; then
    echo -e "$ERROR Start line is greater than End line."
    exit 1
fi

# Check that start-line is positive.
if [ "$START" -lt 0 ]; then
    echo -e "$ERROR Start line is less than 0."
    exit 1
fi

# Check that end-line is positive.
if [ "$END" -lt 0 ]; then
    echo -e "$ERROR End line is less than 0."
    exit 1
fi

NUMOFLINES=$(wc -l < "$FILENAME")

# Check that end-line is not greater than the number of lines in the file.
if [ "$END" -gt "$NUMOFLINES" ]; then
    echo -e "$ERROR End line is greater than number of lines in file."
    exit 1
fi

# The distance from the end of the file to end-line
ENDDIFF=$(( NUMOFLINES - END ))

# For larger files, this will run more quickly. If the distance from the
# end of the file to the end-line is less than the distance from the
# start of the file to the start-line, then start pinching from the
# bottom as opposed to the top.
if [ "$START" -lt "$ENDDIFF" ]; then
    < "$FILENAME" head -n $END | tail -n +$START
else
    < "$FILENAME" tail -n +$START | head -n $(( END-START+1 ))
fi

# Success
exit 0

1
এটি অনেক বিকল্পের চেয়ে ধীর কারণ এটি 2 কমান্ড ব্যবহার করে যেখানে 1 পর্যাপ্ত। প্রকৃতপক্ষে, এটি wcকমান্ডের কারণে ফাইলটি দু'বার পড়ে , যা ডিস্ক ব্যান্ডউইথকে নষ্ট করে, বিশেষত গিগাবাইট ফাইলগুলিতে। সকল প্রকারে, এটি ভালভাবে নথিভুক্ত করা হয়েছে তবে এটি ইঞ্জিনিয়ারিং ওভারকিলও রয়েছে।
জোনাথন লেফলার

1

এটি আপনার (জিএনইউ সেড) কাজ করতে পারে:

sed -ne '16224,16482w newfile' -e '16482q' file

বা ব্যাশের সুবিধা নিচ্ছেন:

sed -n $'16224,16482w newfile\n16482q' file

1

এড ব্যবহার:

ed -s infile <<<'16224,16482p'

-sডায়গনিস্টিক আউটপুট দমন করে; আসল কমান্ডগুলি এখানে একটি স্ট্রিংয়ে রয়েছে। বিশেষ করে, 16224,16482pরান pআকাঙ্ক্ষিত লাইন ঠিকানা ব্যাপ্তির উপর (মুদ্রণ) কমান্ড।


0

- গ্রহণযোগ্য উত্তর কাজ করে। আপনি ঝুঁকির ক্ষেত্রে এখানে আরও একটি উপায়।

cat $filename | sed "${linenum}p;d";

এটি নিম্নলিখিতগুলি করে:

  1. কোনও ফাইলের বিষয়বস্তুগুলিতে পাইপ (বা আপনি চাইলে পাঠ্যে ফিড দিন)।
  2. সেড প্রদত্ত রেখাটি নির্বাচন করে, এটি মুদ্রণ করে
  3. d লাইন মুছে ফেলা প্রয়োজন, অন্যথায় সেড সব লাইন শেষ পর্যন্ত মুদ্রণ করা হবে ধরে নিতে হবে। অর্থাত্, ডি ব্যতীত, আপনি নির্বাচিত লাইনটি মুদ্রণ করে দুটি বার মুদ্রণ পেতে পারেন কারণ আপনার কাছে {{লিনেনাম it পি অংশ এটি মুদ্রণের জন্য জিজ্ঞাসা করছে। আমি নিশ্চিত যে -n মূলত এখানে ডি এর মতো একই কাজ করছে।

3
নোটটি cat file | sedআরও ভালভাবে লেখা হয়েছেsed file
18:53

এছাড়াও এটি কেবল একটি লাইন প্রিন্ট করে, যেখানে প্রশ্নটি তাদের একটি ব্যাপ্তির বিষয়ে।
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

0

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

myfile content:
=====================
line1 not needed
line2 also discarded
[Data]
first data line
second data line
=====================
sed -n '/Data/,$p' myfile

[ডেটা] লাইন এবং বাকীটি মুদ্রণ করবে। আপনি যদি পাঠ্যটি লাইন 1 থেকে প্যাটার্নে চান তবে আপনি টাইপ করুন: সেড-এন '1, / ডেটা / পি' মাইফাইল। তদ্ব্যতীত, আপনি যদি দুটি প্যাটার্ন জানেন (ভাল আপনার পাঠ্যের ক্ষেত্রে অনন্য হতে পারেন) তবে পরিসরের শুরু এবং শেষ লাইন উভয়ই ম্যাচগুলির সাথে নির্দিষ্ট করা যেতে পারে।

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