গ্রেপ ম্যাচ এবং এক্সট্রাক্ট


10

আমার কাছে একটি ফাইল রয়েছে যা এতে লাইন রয়েছে

proto=tcp/http  sent=144        rcvd=52 spkt=3 
proto=tcp/https  sent=145        rcvd=52 spkt=3
proto=udp/dns  sent=144        rcvd=52 spkt=3

আমি প্রোটো যা মান বের করে আনতে প্রয়োজন tcp/http, tcp/https, udp/dns

এখন পর্যন্ত আমি এটি চেষ্টা করেছি grep -o 'proto=[^/]*/'তবে কেবল মানটি বের করতে সক্ষম হয়েছি proto=tcp/



এটি একটি কাজ sed, awkবা perlনা জন্য grep
অরেঞ্জডগ

উত্তর:


1

এটি আপনার আগের প্রশ্নের সাথে সম্পর্কিত বলে ধরে নেওয়া , আপনি ভুল পথে চলেছেন। স্ক্রিপ্টগুলির বিটগুলি একসাথে টুকরো টুকরো করার চেষ্টা করার চেয়ে যা আপনি বেশিরভাগ সময় যা চান তা করতে চান এবং প্রতিবার যখন কিছুটা আলাদা করার দরকার হয় তখন পুরোপুরি আলাদা স্ক্রিপ্ট পাওয়ার প্রয়োজন হয়, কেবল 1 টি স্ক্রিপ্ট তৈরি করুন যা আপনার পার্স করতে পারে একটি অ্যারেতে ইনপুট ফাইল ( f[]নীচে) যা আপনার ক্ষেত্রের নামগুলি (ট্যাগগুলি) তাদের মানগুলিতে মানচিত্র করে এবং তারপরে ফলাফলের সাথে আপনি যা খুশি তা করতে পারেন, যেমন আপনার পূর্ববর্তী প্রশ্ন থেকে এই ইনপুট ফাইলটি দেওয়া:

$ cat file
Feb             3       0:18:51 17.1.1.1                      id=firewall     sn=qasasdasd "time=""2018-02-03"     22:47:55        "UTC""" fw=111.111.111.111       pri=6    c=2644        m=88    "msg=""Connection"      "Opened"""      app=2   n=2437       src=12.1.1.11:49894:X0       dst=4.2.2.2:53:X1       dstMac=42:16:1b:af:8e:e1        proto=udp/dns   sent=83 "rule=""5"      "(LAN->WAN)"""

আমরা একটি awk স্ক্রিপ্ট লিখতে পারি যা তাদের নাম / ট্যাগ দ্বারা সূচিত মানগুলির একটি অ্যারে তৈরি করে:

$ cat tst.awk
{
    f["hdDate"] = $1 " " $2
    f["hdTime"] = $3
    f["hdIp"]   = $4
    sub(/^([^[:space:]]+[[:space:]]+){4}/,"")

    while ( match($0,/[^[:space:]]+="?/) ) {
        if ( tag != "" ) {
            val = substr($0,1,RSTART-1)
            gsub(/^[[:space:]]+|("")?[[:space:]]*$/,"",val)
            f[tag] = val
        }

        tag = substr($0,RSTART,RLENGTH-1)
        gsub(/^"|="?$/,"",tag)

        $0 = substr($0,RSTART+RLENGTH)
    }

    val = $0
    gsub(/^[[:space:]]+|("")?[[:space:]]*$/,"",val)
    f[tag] = val
}

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

$ awk -f tst.awk -e '{for (tag in f) printf "f[%s]=%s\n", tag, f[tag]}' file
f[fw]=111.111.111.111
f[dst]=4.2.2.2:53:X1
f[sn]=qasasdasd
f[hdTime]=0:18:51
f[sent]=83
f[m]=88
f[hdDate]=Feb 3
f[n]=2437
f[app]=2
f[hdIp]=17.1.1.1
f[src]=12.1.1.11:49894:X0
f[c]=2644
f[dstMac]=42:16:1b:af:8e:e1
f[msg]="Connection"      "Opened"
f[rule]="5"      "(LAN->WAN)"
f[proto]=udp/dns
f[id]=firewall
f[time]="2018-02-03"     22:47:55        "UTC"
f[pri]=6

$ awk -f tst.awk -e '{print f["proto"]}' file
udp/dns

$ awk -f tst.awk -e 'f["proto"] ~ /udp/ {print f["sent"], f["src"]}' file
83 12.1.1.11:49894:X0

2
এটি দুর্দান্ত, আপনাকে অনেক ধন্যবাদ :)
ব্যবহারকারীর 356831

এই ধরণের কাজের জন্য, perlব্যবহার করা সহজ হতে পারে।
অরেঞ্জডগ

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

@ এডমার্টন সত্য, যদিও আমি ব্যক্তিগতভাবে এমন কোনও বিতরণের মুখোমুখি হইনি যেখানে পারল ডিফল্টরূপে অন্তর্ভুক্ত ছিল না। জটিল awkএবং sedস্ক্রিপ্টগুলি সাধারণত সহজ হয় perlকারণ এটি সাধারণ কাজের জন্য অতিরিক্ত বৈশিষ্ট্য সহ মূলত সেগুলির একটি সুপারস্টার।
অরেঞ্জডগ

@ ওরেঞ্জডগ কারও কারওর মতো সেড স্ক্রিপ্টটি কখনও লেখা উচিত নয় যা এর চেয়ে জটিল s/old/new/gএবং সেড বিশ্রী নয় তাই এটিকে আলাদা করে দেওয়া যাক। আমি সম্পূর্ণরূপে একমত নই যে জটিল অজস্ক্র স্ক্রিপ্টগুলি পারলে সহজ। তারা অবশ্যই উদ্বিগ্ন হতে পারে তবে সংক্ষিপ্ততা সফ্টওয়্যারগুলির একটি পছন্দসই গুণ নয়, সংক্ষিপ্ততা এবং তাদের পক্ষে সত্যিকারের কোনও উপকার পাওয়া খুব বিরল কারণ তারা সাধারণত পড়াশোনা আরও বেশি কঠিন কারণ এই কারণেই লোকেরা zoitz.com এর মতো জিনিস পোস্ট করে why / আর্কাইভ / 13 পার্ল সম্পর্কে এবং এটিকে বিশ্রী থেকে আলাদা করে কেবলমাত্র লেখার ভাষা হিসাবে উল্লেখ করুন। আমি এখনও এটির মতো পার্ল দেখতে চাই
এড মর্টন

13

এর সাথে grep -o, আপনি কী বের করতে চান ঠিক তার সাথে মিলতে হবে। যেহেতু আপনি proto=স্ট্রিংটি বের করতে চান না , আপনার এটির সাথে মিল পাওয়া উচিত নয়।

একটি বর্ধিত নিয়মিত অভিব্যক্তি যা মিলে যাবে tcpবা তার udpপরে স্ল্যাশের সাথে মিলবে এবং কিছু খালি অ্যালফানিউমারিক স্ট্রিং

(tcp|udp)/[[:alnum:]]+

আপনার ডেটাতে এটি প্রয়োগ করা:

$ grep -E -o '(tcp|udp)/[[:alnum:]]+' file
tcp/http
tcp/https
udp/dns

আমরা কেবল স্ট্রিংয়ের সাথে শুরু হওয়া লাইনে এটি করি তা নিশ্চিত করার জন্য proto=:

grep '^proto=' file | grep -E -o '(tcp|udp)/[[:alnum:]]+'

সঙ্গে sedপ্রথম আগে সবকিছু সরানো, =এবং প্রথম ফাঁকা অক্ষর পরে:

$ sed 's/^[^=]*=//; s/[[:blank:]].*//' file
tcp/http
tcp/https
udp/dns

স্ট্রিং দিয়ে শুরু হওয়া লাইনে আমরা এটিই করি তা নিশ্চিত করার জন্য proto=, আপনি grepউপরের মতো একই প্রাক প্রসেসিং পদক্ষেপটি সন্নিবেশ করতে পারেন, বা আপনি ব্যবহার করতে পারেন

sed -n '/^proto=/{ s/^[^=]*=//; s/[[:blank:]].*//; p; }' file

এখানে, আমরা -nবিকল্পটি দিয়ে ডিফল্ট আউটপুটটি দমন করি এবং তারপরে লাইনটি মেলে তবেই আমরা বিকল্পগুলি এবং লাইনটির একটি স্পষ্ট প্রিন্ট ট্রিগার করি ^proto=


সাথে awk, ডিফল্ট ক্ষেত্র বিভাজক ব্যবহার করে এবং তারপরে প্রথম ক্ষেত্রটি বিভক্ত করে =এবং এর দ্বিতীয় বিটটি মুদ্রণ করে:

$ awk '{ split($1, a, "="); print a[2] }' file
tcp/http
tcp/https
udp/dns

স্ট্রিং দিয়ে শুরু হওয়া লাইনে আমরা এটিই করি তা নিশ্চিত করার জন্য proto=, আপনি grepউপরের মতো একই প্রাক প্রসেসিং পদক্ষেপটি সন্নিবেশ করতে পারেন, বা আপনি ব্যবহার করতে পারেন

awk '/^proto=/ { split($1, a, "="); print a[2] }' file

10

আপনি যদি জিএনইউ গ্রেপ ( -Pবিকল্পের জন্য) এ থাকেন তবে আপনি ব্যবহার করতে পারেন:

$ grep -oP 'proto=\K[^ ]*' file
tcp/http
tcp/https
udp/dns

আমরা proto=সঠিক কলামটি বের করছি কিনা তা নিশ্চিত করার জন্য এখানে আমরা স্ট্রিংয়ের সাথে মিল রেখেছি, তবে তারপরে আমরা \Kপতাকাটির সাহায্যে আউটপুট থেকে এটি বাতিল করি ।

উপরেরটি ধরে নেওয়া হয়েছে যে কলামগুলি স্থান-বিভাজিত। যদি ট্যাবগুলিও একটি বৈধ বিভাজক হয়, তবে আপনি \Sঅ-হোয়াইটস্পেস অক্ষরের সাথে মিল রাখতে ব্যবহার করতে পারেন , সুতরাং আদেশটি হ'ল:

grep -oP 'proto=\K\S*' file

আপনি যদি ম্যাচের ক্ষেত্রগুলি থেকে proto=বিরত thisisnotaproto=tcp/httpsরাখতে চান তবে সাবস্ট্রিং যেমন একটি , আপনি শব্দের সীমানা এর \bমতো যুক্ত করতে পারেন:

grep -oP '\bproto=\K\S*' file

1
আপনি শুধু লিখে লিখে উন্নতি করতে পারেন grep -oP 'proto=\K\S+'proto=tcp/httpশূণ্যস্থান পরিবর্তে একটি ট্যাব দ্বারা অনুসরণ হতে পারে এবং \Sঅসদৃশ [^ ]কোনো অ-স্পেস চরিত্র ম্যাচ হবে।
মশবি

@ মোসভি: এটি একটি ভাল পরামর্শ, ধন্যবাদ।
ব্যবহারকারী000001

1
যাইহোক, -oপাশাপাশি একটি GNUism। পিসিআরই সমর্থন (বিল্ড সময়ে alচ্ছিক) দিয়ে তৈরি হলে -Pকেবল grepজিএনইউই সমর্থন করে।
স্টাফেন চেজেলাস

6

ব্যবহার awk:

awk '$1 ~ "proto" { sub(/proto=/, ""); print $1 }' input

$1 ~ "proto"আমরা নিশ্চিত করব যে আমরা কেবল protoপ্রথম কলামে লাইনগুলিতে ব্যবস্থা নেব

sub(/proto=/, "")proto=ইনপুট থেকে সরানো হবে

print $1 বাকী কলামটি মুদ্রণ করে


$ awk '$1 ~ "proto" { sub(/proto=/, ""); print $1 }' input
tcp/http
tcp/https
udp/dns

3

grepসমাধানগুলিতে কোড গল্ফিং

grep -Po "..p/[^ ]+" file

অথবা এমনকি

grep -Po "..p/\S+" file

3

cutকমান্ডটি ব্যবহার করে :

cut -b 7-15 foo.txt

3
এর মধ্যে লাইন httpএবং dnsলাইনে স্থানের স্থান অন্তর্ভুক্ত থাকবে ।
জি-ম্যান

2

আরও একটি grepসমাধান:

grep -o '[^=/]\+/[^ ]\+' file

এবং sedকেবল মিলিত ক্যাপচার গোষ্ঠীটির মুদ্রণের সাথে একটি অনুরূপ :

sed -n 's/.*=\([^/]\+\/[^ ]\+\).*/\1/p' file

1

অন্য awkপদ্ধতি:

$ awk -F'[= ]' '/=(tc|ud)p/{print $2}' file
tcp/http
tcp/https
udp/dns

এটি উভয়ের ক্ষেত্র বিভাজককে =একটি বা একটি স্পেসে সেট করবে । তারপরে, যদি লাইনটি একটির সাথে মেলে =, তবে হয় udবা তার tcপরে একটি p, দ্বিতীয় ক্ষেত্রটি মুদ্রণ করুন।

আর একটি sedপদ্ধতি (সমস্ত সংস্করণে বহনযোগ্য নয় sed, তবে জিএনইউতে কাজ করে sed):

$ sed -En 's/^proto=(\S+).*/\1/p' file 
tcp/http
tcp/https
udp/dns

এর -nঅর্থ "মুদ্রণ করবেন না" এবং -Eবর্ধিত নিয়মিত অভিব্যক্তি সক্ষম করে যা আমাদের \S"নন-হোয়াইটস্পেস", +"এক বা একাধিক" এবং ক্যাপচারের জন্য প্রথম বন্ধনের জন্য দেয়। অবশেষে, /pবিকল্পটি অপারেটরের জন্য কোনও মিল থাকলে অপারেশনটি সফল হলে কেবল শেষে একটি লাইন প্রিন্ট করবে।

এবং, একটি পার্ল:

$ perl -nle '/^proto=(\S+)/ && print $1' file 
tcp/http
tcp/https
udp/dns

এর -nঅর্থ "ইনপুট ফাইল লাইনটি লাইনে পড়ুন এবং -eপ্রতিটি লাইনের দ্বারা প্রদত্ত স্ক্রিপ্টটি প্রয়োগ করুন "। -lপ্রতিটি একটি newline যোগ printকল (এবং ইনপুট থেকে প্রস্থান নতুন লাইন সরিয়ে ফেলা হবে)। স্ক্রিপ্ট নিজেই একটির পরে পাওয়া শ্বেতস্থান অক্ষরের দীর্ঘতম প্রসারকে মুদ্রণ করবে proto=


1
-Eআরও বেশি পোর্টেবল হচ্ছে, তবে \Sতা নয়। [^[:space:]]আরও বেশি বহনযোগ্য সমতুল্য।
স্টাফেন চেজেলাস

1

এখানে আরও একটি সহজ সমাধান রয়েছে:

grep -o "[tc,ud]*p\\/.*  "   INPUTFile.txt  |   awk '{print $1}'

আপনার grepকোনও কিছুর সাথে মেলে না। [tc,ud]\*\\/.*জন্য দেখায় এক পারেন সংঘটন t, অথবা c, অথবা ,বা uবা d, একটি আক্ষরিক দ্বারা অনুসরণ *, চরিত্র তারপর একটি pএবং একটি ব্যাকস্ল্যাশ। আপনি সম্ভবত বোঝানো grep -Eo '(tc|ud)p/.* ' file | awk '{print $1}'। কিন্তু তারপর, আপনি awk ব্যবহার করছেন, তাহলে আপনাকে পাশাপাশি পুরো জিনিস awk না করতে পারেন: awk -F'[= ]' '/(tc|ud)p/{print $2}' file
টেরডন

কেউ আমার আসলটি পরিবর্তন করেছেন, তারার আগে একটি অতিরিক্ত ব্যাকস্ল্যাশ ছিল যা আমি স্যারকে সরিয়েছি।
mkzia

সম্পাদনার জন্য ধন্যবাদ, তবে আমি আশঙ্কা করছি যে এটি কেবল সুযোগে কাজ করে। হিসাবে আমি আগে ব্যাখ্যা, [tc,ud]pমানে হলো "এক t, c, ,, uবা dএকটি দ্বারা অনুসরণ p। সুতরাং তা এখানে মিলে যায় শুধুমাত্র কারণ tcpহয়েছে cpএবং udpহয়েছে dp। কিন্তু এটি মেলে দিবে ,pবা tpইত্যাদি এছাড়াও, এখন আপনি আছে *, এটা ম্যাচ হবে pppপাশাপাশি ( *"" বা তার বেশি "এর অর্থ এটি মিলবে না এমনকি এটি মিলবে না। আপনি একটি অক্ষর শ্রেণি ( [ ]) চান না , যা আপনি চান তা একটি গ্রুপ: (tc|ud)(এর -Eপতাকা সহ ব্যবহার করুন grep) Also এছাড়াও, এটি .*এটি তৈরি করে পুরো লাইনটি মেলে।
টেরডন

1
@ জেসি_বি: যদিও এমকিজিয়া প্রযুক্তিগতভাবে একটি "নতুন অবদানকারী" নয়, তারা অনভিজ্ঞ ব্যবহারকারী, তাদের প্রমাণ হিসাবে তারা তাদের কমান্ডের জন্য কোড বিন্যাস ব্যবহার করেন নি। এবং তবুও তারা যথাযথভাবে টাইপ \*করতে পারে *যাতে তাদের কমান্ডের প্রথম হিসাবে * হিসাবে প্রদর্শিত হয় এবং এটি ইটালিকস মার্কডাউন হিসাবে নয়। আপনি যখন কোডটি বিন্যাসে কমান্ডটি রেখেছিলেন, আপনি আগেটি উপস্থিত \হওয়ার আগে *ঘটিয়েছিলেন (এভাবে আদেশটি ব্যর্থ হওয়ার কারণ)। আপনি যখন অন্য ব্যক্তির পোস্টগুলি সম্পাদনা করেন, দয়া করে পোস্টটির উপস্থিতি পরিবর্তনের জন্য নজর রাখুন।
জি-ম্যান

@ ইটারডন: (১) না, আসলে এটি মেলে না ppp। অবশ্যই তুমি ডান এটি ম্যাচ হবে ,pবা  tp- বা uucp, ttp, cutp, ductpবা d,up
জি-ম্যান


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