ন্যূনতম অক্ষরের সাথে কীভাবে লাইন পাবেন


22

আমি কোনও সাধারণ UNIX কমান্ড ব্যবহার করে একটি শেল স্ক্রিপ্ট লিখছি। আমাকে সর্বনিম্ন অক্ষর রয়েছে এমন লাইনটি পুনরুদ্ধার করতে হবে (সাদা স্থান অন্তর্ভুক্ত)। প্রায় 20 টি লাইন থাকতে পারে।

আমি জানি যে আমি head -$L | tail -1 | wc -mলাইন এল এর চরিত্রের গণনাটি খুঁজে পেতে ব্যবহার করতে পারি , সমস্যাটি হ'ল, এটি ব্যবহার করে আমি একমাত্র পদ্ধতিটি মানগুলির সাথে তুলনা করে ম্যানুয়ালি বিবৃতি লিখতে পারি।

উদাহরণ ডেটা:

seven/7
4for
8 eight?
five!

4forযে লাইনে কমপক্ষে অক্ষর ছিল সেহেতু ফিরে আসবে ।

আমার ক্ষেত্রে, যদি একাধিক লাইনের সংক্ষিপ্ত দৈর্ঘ্য থাকে তবে একটি একক ফেরত দেওয়া উচিত। কোনটি নির্বাচিত তা বিবেচনা করে না, যতক্ষণ না এটি ন্যূনতম দৈর্ঘ্যের হয়। তবে অন্যান্য পরিস্থিতিতে অন্যান্য ব্যবহারকারীর জন্য উভয় উপায় দেখানোর ক্ষতি আমি দেখতে পাচ্ছি না।


5
4 দৈর্ঘ্যের একাধিক লাইন থাকলে কী হবে? সেগুলিও কি ছাপা উচিত?
বিশৃঙ্খলা

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

উত্তর:


13

একটি পার্ল উপায়। মনে রাখবেন যে যদি একই, সংক্ষিপ্ত দৈর্ঘ্যের অনেকগুলি লাইন থাকে তবে এই পদ্ধতিটি কেবল তাদের মধ্যে একটি মুদ্রণ করবে:

perl -lne '$m//=$_; $m=$_ if length()<length($m); END{print $m if $.}' file 

ব্যাখ্যা

  • perl -lne: এর -nঅর্থ "ইনপুট ফাইল লাইনটি লাইনে পড়ুন", এর -lফলে প্রতিটি ইনপুট লাইন থেকে ট্রেলিং করা নিউলাইনগুলি এবং প্রতিটি printকলটিতে একটি নতুন লাইন যুক্ত করা যায় ; এবং -eস্ক্রিপ্ট যা প্রতিটি লাইনে প্রয়োগ করা হবে।
  • $m//=$_: সংজ্ঞায়িত না $mহলে বর্তমান লাইনে সেট করুন ( $_) $m//=অপারেটর পার্ল 5.10.0 যেহেতু পাওয়া যায়।
  • $m=$_ if length()<length($m): যদি বর্তমান মানের $mদৈর্ঘ্য বর্তমান লাইনের দৈর্ঘ্যের চেয়ে বেশি হয় তবে বর্তমান লাইনটি ( $_) হিসাবে সংরক্ষণ করুন $m
  • END{print $m if $.}: একবার সমস্ত লাইন প্রক্রিয়া করা হয়ে $mগেলে, সংক্ষিপ্ততম রেখার বর্তমান মানটি মুদ্রণ করুন । if $.নিশ্চিত এমনটি শুধুমাত্র তখনই ঘটে যখন লাইন নম্বর ( $.), সংজ্ঞায়িত করা হয় ফাঁকা ইনপুট জন্য একটি খালি লাইন মুদ্রণ এড়ানো।

বিকল্পভাবে, যেহেতু আপনার ফাইলটি মেমরিতে ফিট করার পক্ষে যথেষ্ট ছোট, আপনি এটি করতে পারেন:

perl -e '@K=sort{length($a) <=> length($b)}<>; print "$K[0]"' file 

ব্যাখ্যা

  • @K=sort{length($a) <=> length($b)}<>: <>এখানে এমন একটি অ্যারে রয়েছে যার উপাদানগুলি ফাইলের লাইন। sortতাদের দৈর্ঘ্য অনুযায়ী তাদের বাছাই করবে এবং সাজানো লাইন অ্যারে হিসাবে সংরক্ষিত হয় @K
  • print "$K[0]": অ্যারের প্রথম উপাদানটি মুদ্রণ করুন @K: সংক্ষিপ্ততম রেখা।

আপনি যদি সমস্ত সংক্ষিপ্ততম লাইন মুদ্রণ করতে চান তবে আপনি ব্যবহার করতে পারেন

perl -e '@K=sort{length($a) <=> length($b)}<>; 
         print grep {length($_)==length($K[0])}@K; ' file 

1
-Cবাইটের পরিবর্তে অক্ষরের সংখ্যা অনুসারে দৈর্ঘ্য পরিমাপ করতে যোগ করুন । কোনও ইউটিএফ -8 লোকালে, (2 বনাম 3) এর $$চেয়ে কম বাইট রয়েছে , তবে আরও অক্ষর (2 বনাম 1)।
স্টাফেন চেজেলাস

17

সাথে sqlite3:

sqlite3 <<EOT
CREATE TABLE file(line);
.import "data.txt" file
SELECT line FROM file ORDER BY length(line) LIMIT 1;
EOT

এটি এখানে আমার প্রিয়, এসকিউএল কখনও
বিশৃঙ্খলা

2
এটি কোড গল্ফ স্থিতি চালাক
শ্যাডটালকার

2
এটি কি পুরো ফাইলটিকে মেমোরিতে পড়বে এবং / অথবা একটি দ্বিতীয় অন-ডিস্ক অনুলিপি তৈরি করবে? যদি তা হয় তবে এটি চালাক কিন্তু অদক্ষ।
জন কুগেলম্যান মনিকা

1
@ জনকুগেলম্যান এটি সম্ভবত পুরো 4 টি লাইন অস্থায়ী মেমরির কেবলমাত্র ডাটাবেসে ভিজিয়ে দেবে (এটি সেটিকে straceবোঝায়)। আপনার যদি সত্যিই বড় ফাইলগুলির সাথে কাজ করার প্রয়োজন হয় (এবং আপনার সিস্টেমটি অদলবদল করছে না), আপনি কেবল ফাইল নাম যুক্ত করে এটি জোর করতে পারেন sqlite3 $(mktemp)এবং সমস্ত ডেটা ডিস্কে লেখা হবে।
ফ্লোহিমসেল

আমি নিম্নলিখিত ত্রুটিগুলি পেয়েছি: "" "xaa: 8146: আনসকেপড" অক্ষর "" "এবং" "" xaa: 8825: প্রত্যাশিত 1 টি কলাম হয়েছে তবে 2 - অতিরিক্ত উপেক্ষা "" পেয়েছে The ।
আহমেদভ

17

awkপ্রথম পাওয়া সর্বনিম্ন লাইনটি মুদ্রণের জন্য সমাধানের বৈকল্পিক এখানে দেওয়া হয়েছে :

awk '
  NR==1 || length<len {len=length; line=$0}
  END {print line}
'

যা সর্বনিম্ন লাইনগুলি মুদ্রণের জন্য কেবল একটি শর্ত দ্বারা প্রসারিত করা যেতে পারে:

awk '
  length==len {line=line ORS $0}
  NR==1 || length<len {len=length; line=$0}
  END {print line}'
'

12

পাইথনটি মোটামুটি সংক্ষিপ্ত আকারে প্রকাশিত হয় এবং কোডটি টিনে যা বলে তা করে:

python -c "import sys; print min(sys.stdin, key=len),"

চূড়ান্ত কমাটি অস্পষ্ট, আমি স্বীকার করি। এটি মুদ্রণ বিবরণীতে একটি অতিরিক্ত লাইন ব্রেক বন্ধ করে দেয় preven অতিরিক্ত হিসাবে, আপনি পাইথন 3 সমর্থন 0 টি লাইনে এটি লিখতে পারেন:

python3 -c "import sys; print(min(sys.stdin, key=len, default='').strip('\n'))"


টিন কি বলে?
মাইকসার্ভ

@ মাইক্রিজ: এটিতে বলা হয়েছে, "লেনকে কী হিসাবে ব্যবহার করে ন্যূনতম সাইস.স্টদিনের মুদ্রণ" ;-)
স্টিভ জেসোপ

1
Ahh। বাইনারি আকার, নির্ভরতা লতা বা কার্যকর সময় সম্পর্কে কিছুই না, তাহলে?
মাইকজার্ভ

2
@ মিমকিজার: না, ছোট মুদ্রণ টিনে নেই। এটি একটি লক করা ফাইলিং মন্ত্রিসভায় একটি পরামর্শক লিফলেটে রয়েছে, একটি ঘরের মধ্যে, "চিতা থেকে সাবধান" হিসাবে চিহ্নিত একটি দরজার পিছনে।
স্টিভ জেসোপ

গটচা - তাই প্রদর্শন।
মাইকসার্ভ

10

আমি সবসময় খাঁটি শেল স্ক্রিপ্টিং (কোনও এক্সিকিউটি!) দিয়ে সমাধানগুলি পছন্দ করি।

#!/bin/bash
min=
is_empty_input="yes"

while IFS= read -r a; do
    if [ -z "$min" -a "$is_empty_input" = "yes" ] || [ "${#a}" -lt "${#min}" ]; then
        min="$a"
    fi
    is_empty_input="no"
done

if [ -n "$a" ]; then
    if [ "$is_empty_input" = "yes" ]; then
        min="$a"
        is_empty_input="no"
    else
        [ "${#a}" -lt "${#min}" ] && min="$a"
    fi
fi

[ "$is_empty_input" = "no" ] && printf '%s\n' "$min"

দ্রষ্টব্য :

ইনপুটটিতে NUL বাইটস নিয়ে সমস্যা আছে। সুতরাং, পরিবর্তে printf "ab\0\0\ncd\n" | bash this_scriptপ্রিন্ট ।abcd


এটি সত্যিকারের শুদ্ধতম। যদিও, পরীক্ষার আনাড়ি bashআমার sortপরিবর্তে মধ্যবর্তী ফলাফল পাইপ করতে রাজি করবে ।
প্রাচ্য

2
আপনি কি কোনও এক্সিকিউটিভকে বেঞ্চ করার চেষ্টা করেছেন ! সমাধান অন্যদের তুলনায় যা না? এখানে এক্সিকিউটিভের মধ্যে পারফরম্যান্স পার্থক্যের তুলনা করা হয়েছে ! এবং কোন নির্বাহী! একই সমস্যার জন্য সমাধান। পৃথক প্রক্রিয়া সম্পাদন করা খুব কমই উপকারী যখন এটি মাকড়সা করে - ফর্মগুলিতে যেমন var=$(get data)এটি একক প্রসঙ্গে ডেটা প্রবাহকে সীমাবদ্ধ করে - তবে যখন আপনি পাইপলাইনের মাধ্যমে ডেটা সরিয়ে রাখেন - একটি স্ট্রিমে - প্রতিটি প্রয়োগক এক্সিকিউট সাধারণত সহায়ক - কারণ এটি বিশেষজ্ঞকে সক্ষম করে তোলে শুধুমাত্র প্রয়োজন যেখানে মডুলার প্রোগ্রাম প্রয়োগ।
মাইক্রোজার

1
@ ডিজিটাল ট্রামুমা - সংখ্যার একটি প্রসারিত সংক্ষিপ্ত স্ট্রিং শর্ত-উদ্ধৃতি অন্য কোনও প্রসারিত স্ট্রিংয়ের চেয়ে প্রয়োজনীয় শর্তের থেকে কম বা বেশি ছাড় নয়। $IFSডিজিটাল-বৈষম্যমূলক নয় - এমনকি যদি কোনও ডিফল্ট $IFSমানতে না থাকে তবে অনেক শেল একটি প্রিসেট পরিবেশ কনফিগারেশন গ্রহণ করবে $IFS- এবং এটি কোনও বিশেষ নির্ভরযোগ্য ডিফল্ট নয়।
মাইকজারভেজ


1
মতামত এবং upvotes জন্য আপনাকে ধন্যবাদ (কিছু উত্তর আমার উত্তর সংশোধন করার জন্য @ কুংলম যেতে হবে)। সাধারণত আমি অন্যকে প্রতিদিন খাঁটি শেল স্ক্রিপ্টিং অনুশীলনের পরামর্শ দিই না তবে এমন দক্ষতা এমন কিছু চরম অবস্থায় পাওয়া যায় যেখানে স্থির লিঙ্কযুক্ত ব্যতীত অন্য কিছুই /bin/shউপলব্ধ না। এটি আমার /usrহারিয়ে যাওয়া বা কিছু .soক্ষতিগ্রস্থ সুনোস 4 হোস্টের সাথে একাধিকবার হয়েছিল এবং এখন আধুনিক লিনাক্স যুগে আমার মাঝে মাঝে এম্বেড থাকা সিস্টেম বা বুট ব্যর্থতা সিস্টেমের আরআরআরডের সাথে মাঝে মাঝে একইরকম পরিস্থিতি দেখা যায়। ব্যজিবক্স হ'ল আমরা সম্প্রতি যে দুর্দান্ত জিনিস অর্জন করেছি of
ইয়েগশি

9

এখানে একটি খাঁটি zshসমাধান (এটি সর্বনিম্ন দৈর্ঘ্য সহ সমস্ত লাইন মুদ্রণ করে file) থেকে :

IFS=$'\n'; print -l ${(M)$(<file):#${~${(o@)$(<file)//?/?}[1]}}

উদাহরণ ইনপুট:

seven/7
4for
8 eight?
five!
four

আউটপুট হল:

4for
four

আমি মনে করি এটির একটি সংক্ষিপ্ত ব্যাখ্যা প্রয়োজন :-)


প্রথমত, আমরা অভ্যন্তরীণ ক্ষেত্র বিভাজকটিকে নতুন লাইনে সেট করি:

IFS=$'\n';

এখন পর্যন্ত এত ভাল, এখন হার্ড অংশ। ফাঁকা স্থানের পরিবর্তে নিউলাইন দ্বারা পৃথক করা ফলাফল মুদ্রণ printকরতে -lপতাকা ব্যবহার করে ।

এখন, আমরা ভিতরে থেকে শুরু:

$(<file)

ফাইলটি রেখার দ্বারা লাইনে পঠিত হয় এবং অ্যারের হিসাবে বিবেচিত হয়। তারপর:

${(o@)...//?/?}

oপতাকা বলছেন যে ফলাফল, আরোহী অনুক্রমে আদেশ করা উচিত @খুব অ্যারে হিসাবে ফলাফলের আচরণ মানে। ( //?/?) এর পিছনের অংশটি একটি প্রতিস্থাপন এবং এটি সমস্ত অক্ষরকে একটি দ্বারা প্রতিস্থাপন করে ?। এখন:

${~...[1]}

আমরা [1]আপনার ক্ষেত্রে এখন প্রথম অ্যারে উপাদানটি গ্রহণ করি যা সবচেয়ে সংক্ষিপ্ততম ????

${(M)$(<file):#...}

ম্যাচিং প্রতিটি অ্যারের উপাদানগুলিতে পৃথকভাবে সম্পাদন করা হয়, এবং মেলে না এমন অ্যারে উপাদানগুলি সরানো হয় ( M)। মিলবে এমন প্রতিটি উপাদান ????(4 টি অক্ষর) অ্যারেতে থাকে। সুতরাং বাকী উপাদানগুলি হ'ল 4 টি অক্ষর (সংক্ষিপ্ততম))

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

IFS=$'\n'; print -l ${${(M)$(<file):#${~${(o@)$(<file)//?/?}[1]}}[1]}

8
tr -c \\n 1 <testfile |   #first transform every [^\n] char to a 1
grep -nF ''           |   #next get line numbers
paste -d: - testfile  |   #then paste it together with itself
sort  -t: -nk2,2          #then sort on second field

... এবং বিজয়ী ... লাইন 2, এটা মনে হবে।

2:1111:4for
4:11111:five!
1:1111111:seven/7
3:11111111:8 eight?

তবে এর সাথে সমস্যাটি হ'ল প্রতিটি লাইনটি কাজ করার জন্য দৈর্ঘ্যের দ্বিগুণের বেশি হতে হবে - তাই LINE_MAX কার্যকরভাবে অর্ধেক হয়ে যায়। কারণটি এটি ব্যবহার করছে - কোন, বেস 1? - লাইন দৈর্ঘ্য উপস্থাপন। একটি সাদৃশ্যপূর্ণ - এবং সম্ভবত আরও পরিচ্ছন্ন - পদ্ধতির প্রবাহটি সেই তথ্যকে সংকুচিত করতে পারে। আমার কাছে যে রেখাগুলি দেখা দেয় সেগুলির মধ্যে প্রথম ধারণাটি আমার উচিত unexpand:

tr -c \\n \  <testfile    |   #transform all [^\n] to <space>
unexpand -t10             |   #squeeze every series of 10 to one tab
grep -nF ''               |   #and get the line numbers
sed    's/:/!d;=;:/;h;:big    #sed compares sequential lines
$P;$!N; /\(:[^ ]*\)\( *\)\n.*\1.*\2/!D     #newest line is shorter or...
        g;/:./!q;b big'   |   #not; quit input entirely for blank line
sed -f - -e q testfile        #print only first occurrence of shortest line

প্রিন্ট ...

2
4for

অন্য একটি, ঠিক sed:

sed -n '/^\n/D;s/\(.\)\(\n.*\)*/\1/g
$p;h;   s// /g;G;x;n;//!g;H;s// /g
G;      s/^\( *\)\(\n \1 *\)\{0,1\}\n//
D'      <infile >outfile

সিনট্যাক্সটি মানদণ্ডের সাথে সম্মতিযুক্ত - তবে এটি কোনও গ্যারান্টি নয় যে কোনও পুরানো সঠিকভাবে sedপরিচালনা করবে \(reference-group\)\{counts\}- অনেকে তা করেন না।

এটি মূলত বারবার ইনপুটটিতে একই রেজিএক্সপ্যাক্স প্রয়োগ করে - এটি সংকলনের সময় হলে খুব উপকারী হতে পারে। এই নিদর্শনটি হ'ল:

\(.\)\(\n.*\)*

যা বিভিন্নভাবে বিভিন্ন স্ট্রিংয়ের সাথে মেলে। উদাহরণ স্বরূপ:

string1\nstring2\nstring3

... সাথে মিলেছে sমধ্যে \1এবং ''মধ্যে নাল স্ট্রিং \2

1\nstring2\nstring3

... সাথে মিলেছে 1মধ্যে \1এবং \nstring2\nstring3মধ্যে\2

\nstring2\nstring3

... সাথে মিলেছে \nমধ্যে \1এবং ''মধ্যে নাল স্ট্রিং \2\nপ্যাটার্ন স্পেসের শিরোনামে ই-লাইন হওয়ার কোনও সম্ভাবনা থাকলে এটি সমস্যাযুক্ত হবে - তবে /^\n/D, এবং //!gকমান্ডগুলি এটি প্রতিরোধ করতে ব্যবহৃত হয়। আমি [^\n]এই ছোট স্ক্রিপ্টের জন্য অন্যান্য প্রয়োজনীয়তা ব্যবহার করেছি, যা বহনযোগ্যতাকে উদ্বেগজনক করে তুলেছে এবং এটি প্রায়শই ভুলভাবে ব্যাখ্যা করা যায় এমন অনেক উপায়ে আমি সন্তুষ্ট ছিল না। প্লাস, .দ্রুত।

\nstring2
string1

... মেলে \nএবং sআবার \1এবং উভয় পেতে ''মধ্যে নাল স্ট্রিং \2। খালি লাইনগুলি একেবারেই মেলে না।

যখন gনিদর্শনটি নিখরচায় প্রয়োগ করা হয় তখন দুটি পক্ষপাত - উভয় বাম-সর্বাধিক স্ট্যান্ডার্ড পক্ষপাত এবং কম ডানদিকের \nইওলাইন পক্ষপাত - একটি এড়িয়ে যেতে প্রভাবিত করার জন্য প্রতি-ভারসাম্যপূর্ণ। কয়েকটি উদাহরণ:

s/\(.\)\(\n.*\)*/\1:\2/g
s/\(.\)\(\n.*\)*/\2\1:/g
s/\(.\)\(\n.*\)*/\1: /g
s/\(.\)\(\n.*\)*/ :\2/g

... যদি সমস্ত প্রয়োগ করা হয় (পর পর নয়) নিম্নলিখিত স্ট্রিংয়ে ...

string1\nstring2

... এটিকে রূপান্তরিত করবে ...

s:t:r:i:n:g:1:\nstring2
s:t:r:i:n:g:\nstring21:
s:t:r:i:n:g:1: 
 : : : : : : :\nstring2

মূলত আমি রেজিপেক্সটি যে কোনও প্যাটার্ন-স্পেসে প্রয়োগ করি সেখানে কেবল সর্বদা প্রথম লাইনটি পরিচালনা করতে ব্যবহার করি। এটি আমাকে ধরে রাখা সংক্ষিপ্ততম ম্যাচ-এতদূর লাইন এবং অতি সাম্প্রতিক রেখার পরীক্ষার লুপগুলিকে অবলম্বন না করে দুটি ভিন্ন সংস্করণ জাগল করতে সক্ষম করে - প্রতিটি প্রতিস্থাপন প্রয়োগ করে পুরো প্যাটার্ন-স্পেস একবারে পরিচালনা করে।

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

দুর্ভাগ্যজনক যে অন্য একটি প্রয়োজনীয়তা হ্যান্ডেল করার জন্য প্রচুর পরিমাণে বাফার স্যুইচ করা হয় - তবে কমপক্ষে দু'টিই বর্তমান থাকার জন্য প্রয়োজনীয় চারটি লাইনের চেয়ে বেশি কখনও অতিক্রম করে না - এবং তাই এটি ভয়াবহ নয়।

যাইহোক, প্রতিটি চক্রের জন্য প্রথম যেটি ঘটে তা হ'ল স্মরণিত রেখায় একটি রূপান্তর - কারণ কেবলমাত্র অনুলিপিটি সংরক্ষণ করা আসলে আক্ষরিক আসল - এতে ...

^               \nremembered line$

... এবং এর পরে nএক্সপুট ইনপুট লাইনটি কোনও পুরানো বাফারকে ওভাররাইট করে। এটিতে কমপক্ষে একটি একক অক্ষর না থাকলে এটি কার্যকরভাবে উপেক্ষা করা হয়। qপ্রথমটি ফাঁকা রেখায় কেবল ইউটি করা আরও সহজ হবে তবে আমার পরীক্ষার ডেটাগুলির অনেকগুলি ছিল এবং আমি একাধিক অনুচ্ছেদ পরিচালনা করতে চেয়েছিলাম wanted

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

^   \n               \nremembered line\nnew$

শেষটি সেই প্যাটার্ন স্পেসে প্রতিস্থাপন প্রয়োগ করা হয়েছে:

s/^\( *\)\(\n \1 *\)\{0,1\}\n//

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

ফলাফল নির্বিশেষে প্যাটার্ন স্পেসের প্রথম লাইনটি Dআবার শুরু করার আগে চক্রের শেষের দিকে সর্বদা একত্রে থাকে। এর অর্থ হ'ল নতুন লাইনটি যদি স্ট্রিংয়ের চেয়ে কম হয় ...

new

... চক্রের প্রথম প্রতিস্থাপনে ফেরত পাঠানো হয় যা সর্বদা প্রথম নতুন লাইনের চর থেকে সর্বদা ফিরবে - এবং তাই এটি পুরোপুরি থেকে যায়। তবে যদি তা না হয় তবে স্ট্রিং ...

remembered line\nnew

... পরিবর্তে পরবর্তী চক্র শুরু হবে, এবং প্রথম প্রতিস্থাপন এটি থেকে স্ট্রিংটি ছড়িয়ে যাবে ...

\nnew

...প্রত্যেকবার.

একেবারে শেষ লাইনে মনে রাখা রেখাটি স্ট্যান্ডার্ড আউট প্রিন্ট করা হয় এবং উদাহরণস্বরূপ দেওয়া তথ্যের জন্য এটি প্রিন্ট করে:

4for

তবে, গুরুত্ব সহকারে ব্যবহার করুন tr



এমনকি আপনার কি লাইন নম্বর toোকানো প্রয়োজন? আমার ওপি সম্পর্কে আমার পঠনটি হ'ল কেবল সংক্ষিপ্ততম রেখাটি প্রয়োজনীয় এবং সেই লাইনের লাইন নম্বরটিও অগত্যা নয়। আমি এটি সম্পূর্ণতার জন্য প্রদর্শিত কোনও ক্ষতি অনুমান।
ডিজিটাল ট্রমা

@ ডিজিটালট্রামা - না, সম্ভবত না। তবে এগুলি ব্যতীত খুব কমই কার্যকর - এবং এগুলি এত সস্তা come একটি স্ট্রিম কাজ করার সময় আমি সর্বদা আউটপুটে একইভাবে মূল ইনপুট পুনরুত্পাদন করার একটি উপায় অন্তর্ভুক্ত করতে পছন্দ করি - লাইন সংখ্যা এখানে এটি সম্ভব করে তোলে। উদাহরণস্বরূপ, প্রথম পাইপলাইন প্রায় ফলাফল চালু করতে: REINPUT | sort -t: -nk1,1 | cut -d: -f3-। এবং দ্বিতীয়টি হল sed --expressionলেজের অন্য লিপিটি অন্তর্ভুক্ত করার একটি সহজ বিষয় ।
মাইকসার্ভ

@DigitalTrauma - উহু, এবং প্রথম উদাহরণে লাইন সংখ্যা না প্রভাবিত sortটাই ব্রেকার যেমন 'র আচরণ যখন একই দৈর্ঘ্যের লাইন ইনপুট ঘটতে - তাই নিকটতম ঘটছে লাইন সবসময় যে ক্ষেত্রে শীর্ষে floats।
মাইকজারভেট

7

চেষ্টা করুন:

awk '{ print length, $0 }' testfile | sort -n | cut -d" " -f2- | head -1

ধারণাটি হ'ল awkপ্রথমে প্রতিটি লাইনের দৈর্ঘ্য প্রিন্ট করতে হবে। এটি প্রদর্শিত হবে:

echo "This is a line of text" | awk '{print length, $0}'
22 This is a line of text

তারপরে, রেখাগুলি অনুসারে বাছাই করতে sort, গণনা থেকে cutমুক্তি পেতে এবং headপ্রথম লাইনটি রাখার জন্য (স্বল্প অক্ষরের সাথে একটি) অক্ষর গণনাটি ব্যবহার করুন । আপনি অবশ্যই tailএই ক্ষেত্রে সর্বাধিক অক্ষরের সাথে লাইন পেতে ব্যবহার করতে পারেন।

(এটি এই উত্তর থেকে গৃহীত হয়েছিল )


যুক্তিটির জন্য +1 তবে এটি সমস্ত ক্ষেত্রে কার্যকর হবে না। যদি দুটি লাইনে একই সংখ্যার অক্ষর থাকে এবং যা সর্বনিম্ন হয়। এটি আপনাকে কেবল প্রথম লাইনে দেবে যা এর কারণ হিসাবে দেখা হয়েছেhead -1
থিশি

দীর্ঘতম লাইন পেতে, ব্যবহারের চেয়ে ধরণের বিপরীত করা কিছুটা দক্ষ tail(যতক্ষণ headনা এর কাজ শেষ হওয়ার সাথে সাথে তার বাকী ইনপুটটি না পড়েই বেরিয়ে যেতে পারে)।
টবি স্পিড

@ থুশি রেজি সংখ্যাগুলি প্রিন্ট করার পরে, কিছুটা রেইগেক্স ব্যবহার করে, লাইন 1 এর সমান সংখ্যার লাইনগুলি ছাড়াও সমস্ত কিছু সরিয়ে ফেলতে পারে, ফলে সমস্ত সংক্ষিপ্ততম রেখা আউটপুট করে।
ম্যাথু ডি স্কোলফিল্ড

5

পসিক আড্ডা সহ:

awk 'FNR==1{l=$0;next};length<length(l){l=$0};END{print l}' file

যদি একাধিক লাইনে একই সংখ্যার অক্ষর থাকে এবং এটিও সর্বনিম্ন হয় তবে এটি কাজ করবে না।
থুশি

@ থুশি: এটি প্রথম ন্যূনতম লাইনের প্রতিবেদন করবে।
কিউংলম

হ্যাঁ, তবে এটি সঠিক আউটপুটটি সঠিক নয়? এমনকি অন্যান্য লাইনে ন্যূনতম সংখ্যা রয়েছে।
থুশি

1
@ থুশি: এটি ওপি প্রয়োজনীয়তার সাথে উল্লেখ করে না, ওপি থেকে অপেক্ষার আপডেট।
কিউংলম

3
Lভেরিয়েবলের নামকরণের জন্য বেছে নেওয়া সেরা চিঠি বলে আমি মনে করি না : ডি কিছু minএমন বিষয়গুলি আরও পরিষ্কার করে দেবে
fedorqui

3

@ মাইকজার্ভ্সের কিছু ধার ধার করা:

< testfile sed 'h;s/./:/g;s/.*/expr length "&"/e;G;s/\n/\t/' | \
sort -n | \
sed -n '1s/^[0-9]+*\t//p'

প্রথমটি sedনিম্নলিখিতগুলি করে:

  • h মূল লাইনটি হোল্ড বাফারে সংরক্ষণ করে
  • লাইনের প্রতিটি অক্ষরকে এর সাথে প্রতিস্থাপন করুন :- এটি কোড ইঞ্জেকশনের যে কোনও বিপদ দূর করে
  • পুরো লাইনটি এর সাথে প্রতিস্থাপন করুন expr length "whole line"- এটি শেল এক্সপ্রেশন যা মূল্যায়ন করা যেতে পারে
  • ই-কমান্ডটিs হ'ল একটি জিএনইউ সিড এক্সটেনশন যা প্যাটার্ন স্পেসটি মূল্যায়ন করতে এবং ফলাফলটিকে প্যাটার্ন স্পেসে ফিরিয়ে দেয়।
  • G প্যাটার্ন স্পেসে একটি নতুন লাইন এবং হোল্ড স্পেসের (মূল লাইন) সামগ্রীগুলি সংযোজন করে
  • চূড়ান্ত sএকটি ট্যাব দিয়ে নিউলাইন প্রতিস্থাপন

অক্ষরের সংখ্যা এখন প্রতিটি লাইনের শুরুতে একটি সংখ্যা, তাই sort -nলাইন দৈর্ঘ্য অনুসারে বাছাই করা।

ফাইনাল sedতারপরে প্রথম (সংক্ষিপ্ততম) লাইন এবং রেখার দৈর্ঘ্য ব্যতীত সমস্ত অপসারণ করে ফলাফল মুদ্রণ করে।


1
@ মিকসার্ভ হ্যাঁ আমি exprএখানে খুব সুন্দর বলে মনে করি । হ্যাঁ, eপ্রতিটি লাইনের জন্য একটি শেল তৈরি করবে। আমি সেড এক্সপ্রেশনটি এডিট করেছিলাম যাতে এটি স্ট্রের প্রতিটি চরকে প্রতিস্থাপনের :পূর্বে একটি বিভক্তির সাথে প্রতিস্থাপন করে যা আমার মনে হয় কোড ইনজেকশনের কোনও সম্ভাবনা অপসারণ করা উচিত।
ডিজিটাল ট্রমা

আমি সাধারণত xargs exprব্যক্তিগতভাবে বেছে নেব - তবে, একটি মধ্যবর্তী শেল এড়ানো ছাড়া অন্যটি, এটি সম্ভবত আরও স্টাইলিস্টিক জিনিস। আমার পছন্দ হয়েছে, যাই হোক না কেন।
মাইকজারভেজ

3

আমার কাছে এটি ঘটেছিল যে পুরো জিনিসটি একটি sedঅভিব্যক্তিতে সম্ভব । এটি সুন্দর নয়:

$ sed '1h;s/.*/&\n&/;G;:l;s/\n[^\n]\([^\n]*\)\n[^\n]/\n\1\n/;tl;/\n\n/{s/\n.*//;x};${x;p};d' testfile
4for
$ 

এটি ভেঙে:

1h            # save line 1 in the hold buffer (shortest line so far)
s/.*/&\n&/    # duplicate the line with a newline in between
G             # append newline+hold buffer to current line
:l            # loop start
s/\n[^\n]\([^\n]*\)\n[^\n]/\n\1\n/
              # attempt to remove 1 char both from current line and shortest line
tl            # jump back to l if the above substitution succeeded
/\n\n/{       # matches if current line is shorter
  s/\n.*//    # remove all but original line
  x           # save new shortest line in hold buffer
}
${            # at last line
  x           # get shortest line from hold buffer
  p           # print it
}
d             # don't print any other lines

ওএস এক্সে থাকা বিএসডি সেড নিউলাইনগুলি নিয়ে কিছুটা চটজলদি। এই সংস্করণটি বিএসডি এবং জিএনইউ উভয় সংস্করণের জন্য কাজ করে:

$ sed -e '1h;G;s/\([^\n]*\)\(\n\)\(.*\)/\1\2\1\2\3/;:l' -e 's/\(\n\)[^\n]\([^\n]*\n\)[^\n]/\1\2/;tl' -e '/\n\n/{s/\n.*//;x;};${x;p;};d' testfile
4for
$

নোট করুন এটি একটি সর্বোত্তম অনুশীলনের উত্তর দেওয়ার গুরুতর প্রয়াসের চেয়ে "কারণ এটি সম্ভব" উত্তর more আমার ধারণা এটির অর্থ আমি খুব বেশি কোড-কলফ খেলছি


man sedওএস এক্স থেকে মাইক্রোজার : "এস্কেপ সিকোয়েন্স the n প্যাটার্ন স্পেসে এম্বেড করা একটি নতুন লাইনের চরিত্রের সাথে মেলে" । সুতরাং আমি মনে করি জিএনইউ সেড \nরিজেক্সে এবং প্রতিস্থাপনের ক্ষেত্রে অনুমতি দেয়, তবে বিএসডি কেবল \nরেগেক্সে অনুমতি দেয় এবং প্রতিস্থাপনে নয়।
ডিজিটাল ট্রমা

\nপ্যাটার্ন স্পেস থেকে orrowণ নেওয়া ভাল ধারণা এবং এটি দ্বিতীয় s///প্রকাশে কাজ করবে , তবে s/.*/&\n&/ভাবটি \nসেই প্যাটার্ন স্পেসে সন্নিবেশ করছে যেখানে আগে ছিল না one এছাড়াও BSD সেডকে লেবেল সংজ্ঞা এবং শাখার পরে আক্ষরিক নতুন লাইনের প্রয়োজন মনে হয়।
ডিজিটাল ট্রমা

1
এই নিউলাইনগুলি হ'ল প্যারামিটার ডিলিমিটারগুলি - আপনার কোনও কমান্ডটি সীমাবদ্ধ করতে হবে যা একটি স্বেচ্ছাসেবী পরামিতি গ্রহণ করতে পারে - কমপক্ষে, এটাই বলেছে অনুমান। অনুমানটি আরও বলেছে যে sedস্ক্রিপ্টটি একটি টেক্সট ফাইল হবে তবে এটি একটি নতুন লাইনে শেষ হওয়ার দরকার নেই । সুতরাং আপনি সাধারণত এগুলিকে পৃথক আরগ হিসাবেও সীমিত করতে পারেন - sed -e :\ label -e :\ label2ইত্যাদি। যেহেতু আপনি 1hযেভাবেই করছেন , x;Hআপনার নতুন লাইন পাওয়ার উপর ভিত্তি করে আপনি কিছু যুক্তিকে স্যুইচ করতে পারেন - এবং আপনি একটি নতুন লাইন ডাব্লু / এ টান না দিয়ে চক্রের শেষে প্যাটার্ন স্পেস থেকে একটি শীর্ষস্থানীয় নিউলাইনটি ছাঁটাতে পারেন D
মাইক্রজারভ

পছন্দ করেছেন হ্যাঁ, আমি Gপ্রথমে এবং s///এক্সপ্রেশনটি পরিবর্তন করে আমার প্রয়োজনীয় নতুন লাইনটি প্রবেশ করিয়েছি । এটি ব্যবহার করে এটি বিভক্ত করা -eসমস্তকে আক্ষরিক নতুন লাইনের সাথে এক (দীর্ঘ) লাইনে যেতে দেয়।
ডিজিটাল ট্রমা

\nপালাবার জন্য spec'd হয় sed, অত্যধিক এর LHS, এবং আমি মনে করি যে ধারণকৃত বৈশিষ্ট বক্তব্য হয়, ব্যতীত POSIX বন্ধনী এক্সপ্রেশন যেমন একটি উপায় যে সমস্ত অক্ষর তাদের বিশেষ অর্থ হারান মধ্যে spec'd করছেন যে - (স্পষ্টভাবে সহ \\) - বন্ধনী ব্যতীত একটির মধ্যে, পরিসীমা বিভাজক হিসাবে ড্যাশ এবং বিন্দু, সমান, ক্যারেট, কোলেশন, সমতা, অবহেলা এবং শ্রেণি জন্য কোলন।
মাইকসার্ভ

2

আরেকটি পার্ল সমাধান: হ্যাশ-অফ-অ্যারেরে রেখাগুলি সংরক্ষণ করুন, হ্যাশ কীটি লাইন দৈর্ঘ্য। তারপরে, সর্বনিম্ন কী দিয়ে লাইনগুলি মুদ্রণ করুন।

perl -MList::Util=min -ne '
    push @{$lines{ length() }}, $_;
} END {
    print @{$lines{ min keys %lines }};
' sample 
4for

আপনি ব্যবহার করতে পারেন push @{$lines{+length}};এবং print @{$lines{+min keys %lines}};কম টাইপ করার জন্য :)
কিউংলম

আমি যদি গল্ফ করছিলাম তবে আমি ভেরিয়েবল নাম "লাইন" ব্যবহার করতাম না:perl -MList::Util=min -nE'push @{$l{+length}},$_}END{say@{$l{min keys%l}}' sample
গ্লেন জ্যাকম্যান

অ-গল্ফযুক্ত সংস্করণ (যা কাজ করে!) এর জন্য +1, যদিও কেবল সমস্ত প্রকারের মুদ্রণের জন্য । - perlআমরা যারা par.ww perlএর ক্রিপ্টিক প্রকৃতির সাথে আপ না হয় তাদের জন্য কিছুটা কৌতুকপূর্ণ হয় । BTW। গল্ফযুক্ত sayআউটপুট শেষে একটি উত্সাহী ফাঁকা লাইন প্রিন্ট করে।
পিটার.ও

2

প্রথম সংক্ষিপ্ততম রেখাটি পেতে:

f=file; sed -n "/^$(sed 's/./1/g' $f | sort -ns | sed 's/././g;q')$/{p;q}" $f

সমস্ত সংক্ষিপ্ত লিঙ্কগুলি পেতে, কেবলমাত্র এতে পরিবর্তন {p;q}করুনp


আর একটি পদ্ধতি (কিছুটা অস্বাভাবিক) হ'ল দৈর্ঘ্যsort অনুসারে প্রকৃত বাছাই করা । সংক্ষিপ্ত রেখাগুলির সাথেও এটি তুলনামূলকভাবে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে লাইনের দৈর্ঘ্য বৃদ্ধি পাওয়ার সাথে সাথে এটি ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে বেড়ে যায়।
যাইহোক, আমি ওভারল্যাপিং কীগুলি বাছাই করার ধারণাটি বেশ আকর্ষণীয় মনে করি। অন্যরাও এটি আকর্ষণীয় / তথ্যমূলক মনে করতে পারে সে ক্ষেত্রে আমি এটি পোস্ট করছি।

এটি কীভাবে কাজ করে:
একই কী এর দৈর্ঘ্য-বৈকল্পিক অনুসারে বাছাই করুন - key 1যা পুরো লাইনকে ছড়িয়ে দেয়
প্রতিটি ক্রমিক কী রূপটি কী দৈর্ঘ্যের একটি অক্ষর দ্বারা বৃদ্ধি করে, ফাইলের দীর্ঘতম রেখার দৈর্ঘ্য পর্যন্ত (এটি দ্বারা নির্ধারিত wc -L)

সংক্ষিপ্ততম লাইনটির জন্য প্রথম (সাজানো) পেতে:

f=file; sort -t'\0' $(seq -f "-k1.%0.0f" $(<"$f" wc -L) -1 1) "$f" | head -n1

যা একই:

f=file.in; 
l=$(<"$f" wc -L)
k=$(seq -f "-k1.%0.0f" $l -1 1) 
sort -st'\0' $k "$f" | head -n1

2

ধরে নিলাম ফাঁকা রেখাগুলি সবচেয়ে সংক্ষিপ্ত রেখা হিসাবে বিবেচিত হবে না এবং খালি লাইনগুলি উপস্থিত থাকতে পারে, নিম্নলিখিত খাঁটি AWK কাজ করবে:

awk '
    {
        len   = length;
        a[$0] = len
    }
    !len { next }
    !min { min = len }
    len < min { min = len }
    END {
        for (i in a)
            if (min == a[i])
                print i
    }
' infile.txt

2

বাছাই ব্যবহার সম্পর্কে কি?

awk '{ print length($0) "\t" $0 }' input.txt | sort -n | head -n 1 | cut -f2-

1

জিএনইউ অ্যাজকের সাথে

gawk '
    {
         a[length]=$0
    };
    END
    {
        PROCINFO["sorted_in"]="@ind_num_asc";
        for (i in a)
        {
            print a[i]; 
            exit
        }
    }
    ' file
  • প্রতিটি লাইন লাইন দৈর্ঘ্যের দ্বারা সূচিকৃত অ্যারেতে পড়ুন।

  • অ্যারে সূচক দ্বারা আদেশ অনুসারে অ্যারে স্ক্যানিংকে বাধ্যতামূলক PROCINFO["sorted_in"]করতে সেট করুন , সংখ্যা অনুসারে বাছাই করা@ind_num_asc

  • PROCINFOউপরের পদ্ধতিতে সেটিংটি অ্যারের ট্র্যাভার্সালটিতে প্রথমে সবচেয়ে ছোট দৈর্ঘ্যের সাথে রেখাটি বাছাই করতে বাধ্য করে। সুতরাং অ্যারে থেকে প্রথম উপাদানটি মুদ্রণ করুন এবং প্রস্থান করুন

nlognঅন্যান্য কিছু পদ্ধতির nসময়মত থাকার সময় এটির অসুবিধা রয়েছে


1

মাঝারি স্তরের শেল সরঞ্জাম পদ্ধতি, কোনও sedবা সহ awk:

f=inputfile
head -n $(xargs -d '\n' -L 1 -I % sh -c 'exec echo "%" | wc -c' < $f | 
          cat -n | sort -n -k 2 | head -1 | cut -f 1)  $f | tail -1

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