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




command-line sed (15)

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

16২4-4 এবং 1648২ এর মধ্যে একটি ফাইল থেকে সমস্ত লাইন সরিয়ে আনতে এবং তারপর তাদের একটি নতুন ফাইলে পুনঃনির্দেশিত করতে কোনও ইউনিক্স কমান্ড (বা আদেশের সিরিজ) জানতে পারে?


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

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

যেমন

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

$ অর্থ "সর্বশেষ লাইন", তাই প্রথম কমান্ড লাইন 16224 দিয়ে শুরু সমস্ত লাইন মুদ্রণ করে এবং দ্বিতীয় কমান্ডটি মুদ্রণ লাইন 16428 পরে sed ছেড়ে 16428 । (Boxxar এর সমাধানতে q -range এর জন্য 1 যুক্ত করা প্রয়োজন বলে মনে হচ্ছে না।)

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


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

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

বিকল্পভাবে:

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

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


আমি এই দরকারী সমাধান হতে পারে মনে হয়। যদি টেবিল নামটি "ব্যক্তি" হয় তবে আপনি আপনার টেবিলের পুনরুদ্ধারের জন্য প্রয়োজনীয় সমস্ত লাইন পেতে sed ​​ব্যবহার করতে পারেন।

sed -n -e '/DROP TABLE IF EXISTS.*`person `/,/UNLOCK TABLES/p' data.sql  > new_data.sql

এই উত্তরটির উপর ভিত্তি করে, আপনি যে টেবিলের পুনরুদ্ধার করছেন তার জন্য "ড্রপ টেবিল যদি পূর্ববর্তী" অনুপস্থিত থাকে এবং পরবর্তী টেবিলটি মুছে ফেলার জন্য এটি ব্যবহার করার আগে আপনাকে নতুন ফাইলের নীচে কয়েকটি লাইন মুছে ফেলতে হবে।

বিস্তারিত তথ্য here পাওয়া here


আমি একটি ছোট বাশ স্ক্রিপ্ট লিখেছিলাম যা আপনি আপনার কমান্ড লাইন থেকে চালাতে পারেন, যতক্ষণ আপনি আপনার 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

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

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

FNR ফাইলে রেকর্ড করা লাইনের রেকর্ড (লাইন) নম্বর রয়েছে।


আমি মাথা / লেঙ্গুড় কৌশল পোস্ট করতে চলেছি, কিন্তু আসলে আমি সম্ভবত emacs আগুন। ;-)

  1. esc - x goto-line ret 16224
  2. চিহ্ন ( ctrl - স্থান )
  3. এসসি - এক্স গোটো লাইনটি 1648২
  4. এসসি -

নতুন আউটপুট ফাইল খুলুন, ctl-y সংরক্ষণ করুন

আসুন দেখি কি হচ্ছে।


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

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

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

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

গ্রহণ-উত্তর গ্রহণ উত্তর। এখানে আপনি আরেকটি উপায় চাইছেন।

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

এই নিম্নলিখিত কাজ করে:

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

মাথা / পুচ্ছ ব্যবহার করে বেশ সহজ:

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

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

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

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

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

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

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

[তথ্য] লাইন এবং অবশিষ্ট মুদ্রণ করা হবে। যদি আপনি line1 থেকে প্যাটার্নের পাঠ্যটি চান তবে আপনি টাইপ করুন: sed-n '1, / data / p' myfile। অধিকন্তু, যদি আপনি দুইটি প্যাটার্ন জানেন (আপনার পাঠ্যটিতে আরও ভাল হোন), পরিসরের শুরু এবং শেষ লাইন উভয়ই মিলগুলির সাথে নির্দিষ্ট করা যেতে পারে।

sed -n '/BEGIN_MARK/,/END_MARK/p' myfile

awk সঙ্গে অন্য পদ্ধতির আছে:

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

ফাইলটি বিশাল হলে, শেষ পছন্দসই লাইনটি পড়ার পরে এটি exit করা ভাল হতে পারে। এই ভাবে এটি অপ্রয়োজনীয়ভাবে শেষ পর্যন্ত ফাইলটি পড়বে না:

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

sed -n '16224,16482p' < dump.sql


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

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


perl -ne 'print if 16224..16482' file.txt > new_file.txt

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

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

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

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

q - কোন কমান্ড বা ইনপুট প্রক্রিয়াকরণ ছাড়াই প্রস্থান করুন। উল্লেখ্য যে স্বয়ংক্রিয় পিনটি -n বিকল্পটি অক্ষম না থাকলে বর্তমান প্যাটার্ন স্পেস মুদ্রণ করা হয়।

and

একটি sed স্ক্রিপ্টের ঠিকানা নিম্নলিখিত কোনও ফর্ম হতে পারে:

সংখ্যা একটি লাইন নম্বর নির্দিষ্ট করে ইনপুট শুধুমাত্র লাইন মেলে।

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







text-processing