ইওএফ-এ একাধিক নিউলাইনগুলি কীভাবে সরাবেন?


25

আমার কাছে এমন ফাইল রয়েছে যা এক বা একাধিক নতুন লাইনে শেষ হয় এবং কেবল একটি নতুন লাইনেই শেষ হওয়া উচিত। আমি কীভাবে ব্যাশ / ইউনিক্স / জিএনইউ সরঞ্জামের সাহায্যে এটি করতে পারি?

খারাপ ফাইল উদাহরণ:

1\n
\n
2\n
\n
\n
3\n
\n
\n
\n

সংশোধন করা ফাইল উদাহরণ:

1\n
\n
2\n
\n
\n
3\n

অন্য কথায়: ইওএফ এবং ফাইলের শেষ নন-লাইন চরিত্রের মধ্যে ঠিক একটি নতুন লাইন থাকা উচিত।

রেফারেন্স বাস্তবায়ন

ফাইলের সামগ্রীগুলি পড়ুন, শেষ পর্যন্ত আর দুটি নতুন লাইন না আসা পর্যন্ত একক নিউলাইন কেটে দিন, এটি আবার লিখুন:

#! /bin/python

import sys

with open(sys.argv[1]) as infile:
    lines = infile.read()

while lines.endswith("\n\n"):
    lines = lines[:-1]

with open(sys.argv[2], 'w') as outfile:
    for line in lines:
        outfile.write(line)

স্পষ্টকরণ: অবশ্যই, পাইপিং অনুমোদিত, যদি এটি আরও মার্জিত হয়।

উত্তর:


16
awk '/^$/ {nlstack=nlstack "\n";next;} {printf "%s",nlstack; nlstack=""; print;}' file

2
+1: awk এর সমাধানগুলি (প্রায়) সর্বদা মার্জিত এবং পঠনযোগ্য!
অলিভিয়ার ডুলাক

পছন্দ করুন আমি যখন দেখলাম sedপ্রস্তাব আমি শুধু OMG এর ... চিন্তা
Hauke Laging

1
এটি হোমআরব্রু থেকে সর্বশেষ উপলভ্য অ্যাডক ব্যবহার করে ওএসএক্স ম্যাভেরিক্সে কাজ করে না। এটি সঙ্গে ত্রুটি awk: illegal statementbrew install mawkএবং mawkযদিও কমান্ড পরিবর্তন করে ।
tjmcewan

@ নাম আমি প্রশ্নটিও বুঝতে পারি না ...
হউক লেগেছে

যে স্ক্রিপ্টটি স্ক্রিপ্টটিতে কাজ করে না সেগুলি হ'ল একটি খারাপভাবে ভাঙা আঁশ -
এড মর্টন

21

থেকে দরকারী এক লাইন স্ক্রিপ্টের জন্য sed

# Delete all trailing blank lines at end of file (only).
sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba' file

4
ধন্যবাদ, আমি একাধিক ফাইলের জন্য এটি করতে নিম্নলিখিতটি ব্যবহার করেছি: find . -type f -name '*.js' -exec sed --in-place -e :a -e '/^\n*$/{$d;N;};/\n$/ba' {} \;
jakub.g

@ jakub.g জায়গায় এবং পুনরাবৃত্ত হ'ল আমার যা প্রয়োজন তা হ'ল। ধন্যবাদ.
বাটল বাটকস

@ জাকুব.এস. থেকে দুর্দান্ত মন্তব্যে যোগ করতে আপনি ওএস এক্স-তে এই আদেশটি অনুরোধ করতে পারেন:find . -type f -name '*.js' -exec sed -i '' -e :a -e '/^\n*$/{$d;N;};/\n$/ba' {} \;
ডেভেজগোদা

18

যেহেতু আপনার কাছে ইতিমধ্যে আরও উপযুক্ত সরঞ্জামগুলি সেড এবং অ্যাজকের সাথে উত্তর রয়েছে; আপনি এই $(< file)ফাঁকে ফাঁকা লাইনের স্ট্রাইপগুলি সরিয়ে ফেলার সুযোগটি নিতে পারেন ।

a=$(<file); printf '%s\n' "$a" > file

এই সস্তা হ্যাকটি ফাঁকা ফাঁকা লাইনগুলি সরিয়ে ফেলতে কাজ করবে না যেখানে কেবল ফাঁকা রেখাগুলি সরিয়ে ফেলতে ফাঁকা স্থান বা অন্যান্য প্রিন্টিং অক্ষর থাকতে পারে। ফাইলটিতে নাল বাইট থাকলে এটিও কাজ করবে না।

বাশ এবং zsh ছাড়া অন্য শেলগুলিতে $(cat file)পরিবর্তে ব্যবহার করুন $(<file)


আমার কাছে বাগের মতো দেখতে কী দেখায় +1: $ (<ফাইল) ফাইলটি আসলেই পড়ছে না? কেন এটি পিছনে নতুন লাইনের অগ্রাহ্য করে? (এটি ঠিক আছে, আমি এটি পরীক্ষা করে
দেখানোর

2
অলিভিয়ারডুলাক $()নতুন লাইনগুলি পিছনে ফেলেছে । এটি একটি ডিজাইনের সিদ্ধান্ত। আমি ধরে নিচ্ছি যে এটি অন্যান্য স্ট্রিংগুলিতে ইন্টিগ্রেশনকে আরও সহজ করে তুলবে: echo "On $(date ...) we will meet."প্রায় প্রতিটি শেল কমান্ড শেষে যে নিউলাইনটি দেয় তার সাথে মন্দ হবে।
হউক লেগেছে

@ হককিজিং: ভাল কথা, সম্ভবত এটিই সেই আচরণের উত্স
অলিভিয়ার ডুলাক

আমি সংযোজন ফাইল খালি এড়াতে "\ N" একটি বিশেষ ক্ষেত্রে আরো বলেন: [[ $a == '' ]] || printf '%s\n' "$a" >"$file"
ডেভিডচাম্বার্স

কোনও ফাইল শুরুর আগে একাধিক নিউলাইনগুলি সরাতে, প্রক্রিয়াটিতে ট্যাক sertোকান (আমি ম্যাকের উপর gnu কোরিউটিল ব্যবহার করি, তাই আমার জন্য gtac):a=$(gtac file.txt); printf '%s\n' "$a" | gtac > file.txt
r_alex_hall


4

এই প্রশ্নের সঙ্গে বাঁধা হয় , কিন্তু কেউ একটি সুপারিশ করেছে edসমাধান।

এখানে একটি:

ed -s file <<'ED_END'
a

.
?^..*?+1,.d
w
ED_END

বা, সমতুল্য,

printf '%s\n' a '' . '?^..*?+1,.d' w | ed -s file

ed প্রারম্ভকালে আপনাকে ডিফল্টরূপে সম্পাদনা বাফারের শেষ লাইনে রাখবে।

প্রথম কমান্ড ( a) বাফারের শেষে একটি ফাঁকা লাইন যুক্ত করে (সম্পাদনা স্ক্রিপ্টের ফাঁকা লাইনটি এই লাইন, এবং ডট ( .) কেবলমাত্র কমান্ড মোডে ফিরে আসার জন্য) is

দ্বিতীয় কমান্ড ( ?) নিকটবর্তী পূর্ববর্তী লাইনের সন্ধান করে যা কিছু (এমনকি শ্বেত-স্থানের অক্ষর) ধারণ করে এবং তারপরের লাইন থেকে বাফারের শেষে সমস্ত কিছু মুছে ফেলবে।

তৃতীয় কমান্ড ( w) ফাইলটি ডিস্কে ফিরে লিখে দেয়।

মূল ফাইলের শেষে কোনও খালি লাইন না থাকায় যুক্ত হওয়া খালি লাইনটি বাকী ফাইলটি মুছে ফেলা থেকে রক্ষা করে।


3

এখানে একটি পার্ল সমাধান রয়েছে যা একবারে মেমরিতে একাধিক লাইন পড়ার প্রয়োজন হয় না :

my $n = 0;
while (<>) {
    if (/./) {
        print "\n" x $n, $_;
        $n = 0;
    } else {
        $n++;
    }
}

বা, এক-লাইনার হিসাবে:

perl -ne 'if (/./) { print "\n" x $n, $_; $n = 0 } else { $n++ }'

এটি একবারে ফাইলটি একটি লাইন পড়ে এবং প্রতিটি লাইনটি পরীক্ষা করে যে কোনও নন-লাইন অক্ষর রয়েছে কিনা তা পরীক্ষা করে। যদি এটি না হয় তবে এটি একটি পাল্টা বাড়ায়; যদি এটি হয়, এটি কাউন্টার দ্বারা নির্দেশিত নতুন লাইনের সংখ্যা মুদ্রণ করে, লাইনটি নিজেই অনুসরণ করে এবং তারপরে কাউন্টারটিকে পুনরায় সেট করে।

প্রযুক্তিগতভাবে, এমনকি স্মৃতিতে একটি লাইন বাফার করা অপ্রয়োজনীয়; স্থির দৈর্ঘ্যের অংশগুলিতে ফাইলটি পড়া এবং একটি রাষ্ট্রীয় মেশিন ব্যবহার করে অক্ষর দ্বারা অক্ষর প্রক্রিয়াকরণ করে অবিচ্ছিন্ন পরিমাণ মেমরি ব্যবহার করে এই সমস্যার সমাধান করা সম্ভব। তবে, আমি সন্দেহ করি যে সাধারণত ব্যবহৃত ব্যবহারের ক্ষেত্রে অযথা জটিল হবে।


1

আপনার ফাইল যদি মেমরিতে স্লাপ করতে যথেষ্ট ছোট হয় তবে আপনি এটি ব্যবহার করতে পারেন

perl -e 'local($/);$f=<>; $f=~s/\n*$/\n/;print $f;' file

0

পাইথনে (আমি জানি এটি আপনি যা চান তা নয়, তবে এটি অপটিমাইজড হওয়ার চেয়ে অনেক ভাল is খুব লম্বা):

#!/bin/python
import sys
infile = open(sys.argv[1], 'r+')
infile.seek(-1, 2)
while infile.read(1) == '\n':
  infile.seek(-2, 1)
infile.seek(1, 1)
infile.truncate()
infile.close()

নোট করুন যে এটি EOL অক্ষর '\ n' নয় এমন ফাইলে কাজ করে না।


0

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

#!/bin/bash
n=1
while test "$(tail -n $n "$1")" == ""; do
  ((n++))
done
((n--))
truncate -s $(($(stat -c "%s" "$1") - $n)) "$1"

0

এইটি টাইপ করা দ্রুত এবং আপনি যদি সেড জানেন তবে মনে রাখা সহজ:

tac < file | sed '/[^[:blank:]]/,$!d' | tac

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

একটি দ্রুত পরীক্ষায়, 18 এমবি, ,000৪,০০০ লাইন ফাইলে অ্যালেক্সির পদ্ধতির দ্রুততা ছিল (০.০3636 বনাম ০.০4646 সেকেন্ড)।

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