একটি লাইনের শুরুতে একটি নির্দিষ্ট স্ট্রিং গ্রেপিং


20

grep "^$1"সাজানোর কাজ, তবে "$1"গ্রেপ কীভাবে পালাতে পারব এতে কোনও চরিত্রের বিশেষ ব্যাখ্যা করা যায় না?

নাকি এর চেয়ে ভাল উপায় আছে?

সম্পাদনা: আমি অনুসন্ধান করতে চাই না '^$1'তবে গতিশীলভাবে সন্নিবেশিত নির্দিষ্ট স্ট্রিংয়ের সন্ধান করতে চাই যা কেবল কোনও লাইনের শুরুর দিকে থাকলে এটি মিলানো উচিত। এটা কি আমি দ্বারা বোঝানো হচ্ছে $1


আপনি কি ডাবল উদ্ধৃতিগুলির পরিবর্তে একক উদ্ধৃতি ব্যবহার করার চেষ্টা করেছেন grep '^$1'? অথবা আপনি কি $1শেল দ্বারা প্রসারিত হওয়া আটকাতে চান না ?
mnille

@ মনিলে আমি '^ $ 1' এর জন্য অনুসন্ধান করতে চাই না তবে একটি গতিশীল .োকানো স্থির স্ট্রিংয়ের জন্য যা কেবল কোনও লাইনের শুরুর দিকে থাকলে এটি মিলানো উচিত। এটি আমি $ 1 দ্বারা বোঝাতে চাইছি।
পিএসকোকিক

3
আপনি এটি grepদিয়েও করতে পারেন তবে আপনাকে প্রথমে আপনার স্ট্রিংয়ের কোনও বিশেষ চরিত্রের হাত থেকে বাঁচতে হবে যেমনprintf %s ^;printf %s "$1" | sed 's/[][\.*^$]/\\&/g'; } | grep -f- infile
ডোন_ক্রিসটি

@ ডন_ক্রিসটি এটি অন্যান্য উত্তরগুলির চেয়ে ভাল। এটি এক করতে যত্ন?
রোয়াইমা

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

উত্তর:


7

আমি এটি ব্যবহার করে করার কোনও উপায় ভাবতে পারি না grep; ^নিজেই একটি নিয়মিত অভিব্যক্তির অংশ তাই এটি ব্যবহার করার জন্য নিয়মিত ভাবের ব্যাখ্যা করা দরকার requires এটা সাবস্ট্রিংয়ের মিল ব্যবহার তুচ্ছ ব্যাপার awk, perlবা যাই হোক না কেন:

awk -v search="$1" 'substr($0, 1, length(search)) == search { print }'

এতে থাকা সন্ধানের স্ট্রিংগুলি পরিচালনা \করতে আপনি 123 এর উত্তরের মতো একই কৌশল ব্যবহার করতে পারেন :

search="$1" awk 'substr($0, 1, length(ENVIRON["search"])) == ENVIRON["search"] { print }'

এটি স্ট্রিংগুলির জন্য কাজ করবে না\/
123

@ 123 প্রকৃতপক্ষে, আমি এটি পরিচালনা করতে একটি বৈকল্পিক যোগ করেছি।
স্টিফেন কিট

প্রোগ্রামের \\\/\/\/\\\\/মতো দেখা যায় এমন জটিল স্ট্রিংগুলির জন্য এখনও ব্যর্থ \\///\\/হবে। আমি যতদূর অবগত আছি ঠিক তেমন কোন উপায় নেই যা আপনি আগে থেকে কতজন ব্যবহার করবেন তা যদি না জানেন তবে অবধি সঠিকভাবে বেকায়দায় ব্যাকস্ল্যাশগুলি থেকে বাঁচার কোনও উপায় নেই।
123

1
@ ১২৩ ধন্যবাদ, পালানোর প্রক্রিয়াটি এড়াতে আমি পরিবেশের মধ্য দিয়ে যাবার কৌশলটি নিজের মধ্যে রূপ নিয়েছি।
স্টিফেন কিট

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

14

আপনার যদি কেবল কোনও মিল খুঁজে পাওয়া যায় কিনা তা যাচাই করা দরকার, সমস্ত ইনপুট লাইনগুলি পছন্দসই উপসর্গ ( $1) এর দৈর্ঘ্যে কেটে নিন এবং তারপরে স্থির-প্যাটার্ন গ্রেপ ব্যবহার করুন:

if cut -c 1-"${#1}" | grep -qF "$1"; then
    echo "found"
else
    echo "not found"
fi

মিলের লাইনের গণনা পাওয়াও সহজ:

cut -c 1-"${#1}" | grep -cF "$1"

বা সমস্ত মিলে যাওয়া লাইনের লাইন নম্বর (রেখার সংখ্যা 1 থেকে শুরু হবে):

cut -c 1-"${#1}" | grep -nF "$1" | cut -d : -f 1

আপনি মিলে যাওয়া লাইনের পুরো পাঠ্যটি পেতে headএবং রেখার সংখ্যাগুলি ফিড tailকরতে পারেন তবে সেই সময়ে পাইথন বা রুবির মতো আধুনিক স্ক্রিপ্টিং ভাষার পক্ষে পৌঁছানো সহজ।

(উপরের উদাহরণগুলি পোজিক্স গ্রেপ এবং কাটা ধরে ধরেছে search তারা অনুসন্ধান করার জন্য ফাইলটি মান ইনপুট থেকে আসে তবে সহজেই পরিবর্তে কোনও ফাইলের নাম নিতে সক্ষম হয়))

সম্পাদনা: আপনারও নিশ্চিত হওয়া উচিত যে প্যাটার্নটি ( $1) কোনও শূন্য দৈর্ঘ্যের স্ট্রিং নয়। অন্যথায় cutব্যর্থ values may not include zero। এছাড়াও, যদি ব্যাশ ব্যবহার করা set -o pipefailহয় তবে ত্রুটি-প্রস্থানগুলি ধরতে ব্যবহার করুন cut


10

পার্ল ব্যবহার করার একটি উপায় যা ব্যাকস্ল্যাশগুলিকে সম্মান করবে

v="$1" perl -ne 'print if index($_, $ENV{"v"} )==0' file

এটি কমান্ডের জন্য পরিবেশ পরিবর্তনশীল v নির্ধারণ করে, তারপরে ভেরিয়েবলের সূচক 0 বা রেখার সূচনা হলে মুদ্রণ করে।

আপনি awk তে অভিন্নও করতে পারেন

v="$1" awk 'index($0, ENVIRON["v"])==1' file

7

এখানে একটি সর্ব-বাশ বিকল্প রয়েছে, আমি পাঠ্য-প্রক্রিয়াকরণের জন্য ব্যাশের প্রস্তাব দিই না, তবে এটি কার্যকর হয়।

#!/usr/bin/env bash
# searches for $1 at the beginning of the line of its input

len=${#1}
while IFS= read -r line
do
  [[ "${line:0:len}" = "$1" ]] && printf "%s\n" "$line"
done

স্ক্রিপ্ট lenইনপুটযুক্ত প্যারামিটার length 1 এর দৈর্ঘ্য গণনা করে , তারপরে প্রতিটি lenঅক্ষরে $ 1 এর সাথে মেলে কিনা তা দেখতে প্রতিটি লাইনে প্যারামিটার সম্প্রসারণ ব্যবহার করা হয় । যদি তা হয় তবে এটি লাইনটি প্রিন্ট করে।


4

যদি আপনার $1খাঁটি ASCII হয় এবং আপনার grepকাছে -Pবিকল্প রয়েছে (পিসিআরই সক্ষম করার জন্য), আপনি এটি করতে পারেন:

#!/bin/bash

line_start="$1"
line_start_raw=$(printf '%s' "$line_start" | od -v -t x1 -An)
line_start_hex=$(printf '\\x%s' $line_start_raw)
grep -P "^$line_start_hex"

এখানে ধারণাটি হ'ল আক্ষরিক অক্ষরগুলি নির্দিষ্ট করার জন্য grep -Pনিয়মিত অভিব্যক্তিগুলিকে অনুমতি দেয় \xXXযেখানে XXসেই অক্ষরের হেক্স ASCII মান। অক্ষরটি আক্ষরিক সাথে মিলেছে, এমনকি যদি এটি অন্যথায় একটি বিশেষ রেজেক্স অক্ষরও হয়।

odপ্রত্যাশিত রেখার সূচনাটি হেক্স মানগুলির তালিকায় রূপান্তর করতে ব্যবহার করা হয়, যা পরে একসাথে স্ট্রিং করা হয়, প্রতিটি প্রিফিক্স \xদ্বারা উপস্থাপিত হয়। ^তারপরে প্রয়োজনীয় রেজেক্স তৈরি করতে এই স্ট্রিংটিকে চাপ দেওয়া হয়।


যদি আপনার $1ইউনিকোড হয়, তবে এটি বেশ কিছুটা শক্ত হয়ে যায়, কারণ আউটপুট হিসাবে হেক্স বাইটের সাথে অক্ষরের 1: 1 চিঠিপত্র নেই od


3

ফিল্টার হিসাবে:

perl -ne 'BEGIN {$pat = shift} print if /^\Q$pat/' search-pattern

এক বা একাধিক ফাইলে চালান:

perl -ne 'BEGIN {$pat = shift} print if /^\Q$pat/' search-pattern file..

"বরাত দিয়ে metacharacters" perlre নথিপত্রের অধ্যায় ব্যাখ্যা করেছেন:

মেটাচার্যাক্টর উদ্ধৃত করা হচ্ছে

পার্ল মধ্যে Backslashed metacharacters যেমন আলফানিউমেরিক হয় \b, \w, \n। কিছু অন্যান্য নিয়মিত প্রকাশের ভাষার মতো, এখানে কোনও ব্যাকস্ল্যাশড চিহ্ন নেই যা বর্ণমালা নয়। তাই দেখে মনে হচ্ছে যে কিছু \\, \(, \), \[, \], \{, অথবা \}সবসময় একটি আক্ষরিক চরিত্র, না একটি metacharacter হিসেবে ব্যাখ্যা করা হয়। আপনি একবারের জন্য ব্যবহার করতে চান এমন স্ট্রিংয়ে নিয়মিত অভিব্যক্তি মেটাচার্যাক্টারের বিশেষ অর্থ অক্ষম করতে বা উদ্ধৃত করার জন্য এটি একবার সাধারণ আইডিয়ামে ব্যবহৃত হয়েছিল। সমস্ত অ-শব্দ "অক্ষর" কেবল উদ্ধৃত করুন:

    $pattern =~ s/(\W)/\\$1/g;

(যদি use localeসেট করা থাকে, তবে এটি বর্তমান লোকেলের উপর নির্ভর করে)) সমস্ত মেটাচ্যাকার্সের এর বিশেষ অর্থগুলি অক্ষম করার জন্য আজ quotemetaফাংশনটি বা \Qমেটাকোটিং পলায়ন ক্রমটি ব্যবহার করা বেশি সাধারণ :

    /$unquoted\Q$quoted\E$unquoted/

সাবধান হন যদি আপনি \Qএবং এর মধ্যে \Eডাবল কোটিশ ব্যাকস্ল্যাশ ইন্টারপোলেশন আক্ষরিক ব্যাকস্ল্যাশগুলি (ইন্টারপোল্টেড ভেরিয়েবলের অভ্যন্তরে নেই) রাখেন তবে বিভ্রান্তিকর ফলাফল হতে পারে। আপনি মধ্যে আক্ষরিক ব্যাকস্ল্যাশ ব্যবহারের প্রয়োজন হলে \Q...\E, সঙ্গে পরামর্শ perlop মধ্যে "উদ্ধৃত নির্মান পার্স এর রক্তাক্ত বিবরণ"

quotemetaএবং \Qসম্পূর্ণরূপে কোটমেটায় বর্ণিত ।



2

যদি আপনি ব্যবহার না করেন এমন কোনও অক্ষর থাকে তবে আপনি লাইনের শুরুটি চিহ্নিত করতে এটি ব্যবহার করতে পারেন। উদাহরণস্বরূপ, $'\a'(ASCII 007)। এটি কুৎসিত তবে এটি কাজ করবে:

{ echo 'this is a line to match'; echo 'but this is not'; } >file.txt

stuffing=$'\a'    # Guaranteed never to appear in your source text
required='this'   # What we want to match that beginning of a line

match=$(sed "s/^/$stuffing/" file.txt | grep -F "$stuffing$required" | sed "s/^$stuffing//")

if [[ -n "$match" ]]
then
    echo "Yay. We have a match: $match"
fi

আপনার যদি ম্যাচিং রেখা (গুলি) প্রয়োজন না হয় তবে আপনি ট্রেলিংটি ফেলে রেখে sedব্যবহার করতে পারেন grep -qF। তবে এটি awk(বা perl) দিয়ে আরও সহজ ...


0

আপনি যখন কোনও লুপ ছাড়াই কোনও ফাইলটি দেখতে চান আপনি ব্যবহার করতে পারেন:
অনুসন্ধান স্ট্রিংয়ের দৈর্ঘ্য সহ ফাইলটি কেটে দিন

  cut -c1-${#1} < file

নির্দিষ্ট স্ট্রিং এবং রিটার্ন লাইন নম্বরগুলি সন্ধান করুন

  grep -Fn "$1" <(cut -c1-${#1} < file)

ভালো কিছু জন্য লাইন নম্বর ব্যবহার করুন sed -n '3p;11p' file

  sed -n "$(grep -Fn "$1" <(cut -c1-${#1} < file) | sed 's/:.*/p;/' | tr -d '\n')" file

আপনি যখন এই লাইনগুলি মুছতে চান, ব্যবহার করুন

  sed "$(grep -Fn "$1" <(cut -c1-${#1} < file) | sed 's/:.*/d;/' | tr -d '\n')" file
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.