লাইনের এন অক্ষরগুলিতে গ্রেপ প্রসঙ্গ সীমিত করুন


31

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

এটি কাল্পনিক গ্রেপ সুইচের জন্য উদাহরণ আউটপুট হবে Ф :

$ grep -r foo *
hello.txt: Once upon a time a big foo came out of the woods.

$ grep -Ф 10 -r foo *
hello.txt: ime a big foo came of t



3
নকল নয়। এটি প্রায় ± অক্ষর সম্পর্কিত তবে আপনার প্রস্তাবিত বিকল্পটি প্রায় ± লাইন। (আপনার রেফারেন্স Stackoverflow ভাল, যদিও।)
roaima

উত্তর:


22

জিএনইউ সহ grep:

N=10; grep -roP ".{0,$N}foo.{0,$N}" .

ব্যাখ্যা:

  • -o => আপনি যা মেলে তা কেবল মুদ্রণ করুন
  • -P => পার্ল-স্টাইলের নিয়মিত এক্সপ্রেশন ব্যবহার করুন
  • Regex 0 মেলে বলেছেন $Nদ্বারা অনুসরণ অক্ষর foo0 দ্বারা অনুসরণ $Nঅক্ষর।

আপনার যদি জিএনইউ না থাকে grep:

find . -type f -exec \
    perl -nle '
        BEGIN{$N=10}
        print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
    ' {} \;

ব্যাখ্যা:

যেহেতু আমরা আর grepজিএনইউ হওয়ার উপর নির্ভর করতে পারি না grep, তাই আমরা findপুনরাবৃত্তভাবে ফাইলগুলির জন্য অনুসন্ধান করতে ( -rজিএনইউ এর ক্রিয়া grep) ব্যবহার করি। পাওয়া প্রতিটি ফাইলের জন্য, আমরা পার্ল স্নিপেট কার্যকর করি।

পার্ল সুইচ:

  • -n এক লাইনে ফাইল লাইন পড়ুন
  • -l প্রতিটি লাইনের শেষে নিউলাইনটি সরান এবং মুদ্রণের সময় এটি আবার রেখে দিন
  • -e নিম্নলিখিত স্ট্রিং কোড হিসাবে আচরণ করুন

পার্ল স্নিপেট মূলত একই জিনিসটি করছে grep। এটি আপনার পছন্দসই $Nপ্রসঙ্গের অক্ষরের সংখ্যার ক্ষেত্রে একটি ভেরিয়েবল সেট করে শুরু হয় । এর BEGIN{}অর্থ এটি প্রতিটি ফাইলে প্রতিটি লাইনের জন্য একবার নয় একবার মৃত্যুদন্ড কার্যকর করার সময় কার্যকর করা হয়।

প্রতিটি লাইনের জন্য সম্পাদিত বিবৃতিটি রেজেক্সে প্রতিস্থাপন কাজ করে তবে লাইনটি মুদ্রণ করা।

রেজেক্স:

  • যে কোনও পুরানো জিনিসটি অলসভাবে 1 টি লাইন ( ^.*?) এর শুরুতে এবং তার পরে .{0,$N}যেমনটি grepঅনুসরণ করুন এবং fooতারপরে .{0,$N}লাইন ( .*?$) এর শেষ অবধি কোনও পুরানো জিনিসটি আলস্যভাবে মেলান ।
  • আমরা এটির পরিবর্তে $ARGV:$1$ARGVএকটি মায়াবী ভেরিয়েবল যা বর্তমান ফাইলটির নাম পড়ে। $1প্যারেনস কী মিলেছে: এই ক্ষেত্রে প্রসঙ্গে।
  • উভয় প্রান্তে অলস ম্যাচগুলি প্রয়োজনীয় কারণ কোনও লোভী ম্যাচটি ম্যাচটি fooব্যর্থ না করে আগে সমস্ত অক্ষর খায় (যেহেতু .{0,$N}শূন্য বারের সাথে মেলানোর অনুমতি দেওয়া হয়)।

1 এটি, সামগ্রিক ম্যাচটি ব্যর্থ হওয়ার কারণ না হলে কোনও কিছুর সাথে মিল না রাখাকে পছন্দ করুন। সংক্ষেপে, যতটা সম্ভব অক্ষর মেলে।


খুব সুন্দর, ধন্যবাদ. এতে পুরো আউটপুট হাইলাইট করার অপূর্ণতা রয়েছে, কেবল পাঠ্যের জন্য অনুসন্ধান করা হয়নি, তবে শেষটি সংযোজন | grep fooকরে (তবে প্রক্রিয়াটিতে ফাইলের নামটি হারাতে হবে) এর চারপাশে কাজ করা যেতে পারে ।
dotancohen

1
@ ডোটানকোহেন আমি অনুমান করি যে আপনি তাদের সবগুলিই জিততে পারবেন না :)
জোসেফ আর।

ডাব্লু / জিএনইউ grepআপনি পরিবেশের ভেরিয়েবলের মাধ্যমে প্রয়োগ করা পতাকাগুলির ভিত্তিতে ম্যাচের রঙ / অ্যাপ্লিকেশন নির্দিষ্ট করতে পারেন। তাই সম্ভবত আপনি সমস্তকে জিততে পারেন , (কোনও প্রতিশ্রুতি নেই - এমনকি এটি নিশ্চিত যে এটি এ ক্ষেত্রে কাজ করবে) তবে আমি ব্যক্তিগতভাবে এখানে প্রাসঙ্গিকতা দেখতে পাচ্ছি না ... যাই হোক ... খেলতে থাকুন।
মাইক্রজারভ

চমৎকার উত্তর. কেবল একটি নোট, ব্যবহার করে zshআমি উদাহরণ হিসাবে এন = 10 পাস করার জন্য এটি পেতে অক্ষম। আমি export N=10কমান্ড চালানোর আগে যদি এটি কাজ করে । Zsh এর সাথে কাজ করার জন্য উদাহরণকে কীভাবে সামঞ্জস্য করবেন কোনও ধারণা?
গ্যাবে কোপেলি

বাperl -lne 'print "$ARGV: $_" for /.{0,10}foo.{0,10}/g'
স্টাফেন চেজেলাস

20

এটি ব্যবহার করার চেষ্টা করুন:

grep -r -E -o ".{0,10}wantedText.{0,10}" *

-আমরা বলছেন, আপনি বর্ধিত রেজেক্স ব্যবহার করতে চান

-ও বলে, আপনি কেবল ম্যাচ মুদ্রণ করতে চান

-r গ্রেপ ফোল্ডারে পুনরাবৃত্তভাবে ফলাফলের সন্ধান করছে

Regex:

{0,10} বলছে, আপনি কতগুলি নির্বিচার অক্ষর মুদ্রণ করতে চান

একটি স্বেচ্ছাসেবী চরিত্র উপস্থাপন করে (একটি চরিত্র নিজেই এখানে গুরুত্বপূর্ণ ছিল না, কেবল তাদের সংখ্যা)

সম্পাদনা: ওহ, আমি দেখতে পাচ্ছি যে জোসেফ আমার মতো প্রায় একই সমাধানের প্রস্তাব দিয়েছেন: ডি


ধন্যবাদ. যদিও এটি মূলত একই সমাধান, এটি আস্থা-অনুপ্রেরণাজনক যে দুটি ব্যক্তি স্বতঃস্ফূর্তভাবে এটির পরামর্শ দিলে এটিই সেরা পদ্ধতি ।
dotancohen

আপনার স্বাগত, ইউনিক্স সম্প্রদায়কে অবশ্যই সহযোগিতা করতে হবে, আমরা
এটাই

2
যদিও তারা অনুরূপ স্বীকৃত উত্তরটি আমার পক্ষে কার্যকর হয়নি (এখনও লম্বা রেখাগুলি উত্পাদিত হয়েছে), তবে একটি এটি করেছে। এন = 10 এর কৌশলটি ব্যাশ শেলের সাথে কাজ করে না।
meesern

মধ্যে cygwin -E উল্লেখযোগ্যভাবে দ্রুততর চেয়ে -P
বব স্টেইন

2

থেকে নেওয়া হয়েছে: http://www.topbug.net/blog/2016/08/18/truncate-long-matching-lines-of-grep-a-solution-that-preserves-color/ এবং https: // স্ট্যাকওভারফ্লো। কম / A / 39029954/1150462

প্রস্তাবিত পদ্ধতির ".{0,10}<original pattern>.{0,10}"পুরোপুরি ভাল তবে ব্যতীত হাইলাইট করার রঙটি প্রায় গণ্ডগোল হয়। আমি অনুরূপ আউটপুট সহ একটি স্ক্রিপ্ট তৈরি করেছি তবে রঙটিও সংরক্ষণ করা হয়েছে:

#!/bin/bash

# Usage:
#   grepl PATTERN [FILE]

# how many characters around the searching keyword should be shown?
context_length=10

# What is the length of the control character for the color before and after the matching string?
# This is mostly determined by the environmental variable GREP_COLORS.
control_length_before=$(($(echo a | grep --color=always a | cut -d a -f '1' | wc -c)-1))
control_length_after=$(($(echo a | grep --color=always a | cut -d a -f '2' | wc -c)-1))

grep -E --color=always "$1" $2 | grep --color=none -oE ".{0,$(($control_length_before + $context_length))}$1.{0,$(($control_length_after + $context_length))}"

ধরে নেওয়া যাক স্ক্রিপ্ট হিসেবে সংরক্ষিত হয় grepl, তারপর grepl pattern file_with_long_linesকিন্তু ম্যাচিং লাইন প্রদর্শন করা উচিত ম্যাচিং স্ট্রিংয়ের মাত্র 10 অক্ষর।


0

পতাকা cutসহ stdout পাইপিং -b; আপনি গ্রাইপের আউটপুটটি প্রতি লাইনে 1 থেকে 400 বাইটে নির্দেশ করতে পারেন।

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