স্টেটমেন্টে গ্রেপ কমান্ডের সাহায্যে স্ট্রিং অনুসন্ধান কীভাবে রাখবেন?


11

আমি দুটি ফাইলে একাধিক স্ট্রিং অনুসন্ধান করতে চাই। যদি উভয় ফাইলে একটি স্ট্রিং পাওয়া যায়, তবে কিছু তৈরি করুন। একটি স্ট্রিং যদি কেবল একটি ফাইলে পাওয়া যায়, তবে অন্য একটি জিনিস তৈরি করুন।

আমার আদেশগুলি পরবর্তী:

####This is for the affirmative sentence in both files
if grep -qw "$users" "$file1" && grep -qw "$users" "$file2"; then

####This is for the affirmative sentence in only one file, and negative for the other one
if grep -qw "$users" "$file1" ! grep -qw "$users" "$file2"; then

এটি বিবৃতি অস্বীকার এবং নিশ্চিত করার একটি সঠিক উপায়? পিডি আমি কেএসএইচ শেল ব্যবহার করছি।

তুমাকে অগ্রিম ধন্যবাদ.

উত্তর:


11

এটা চেষ্টা কর:

if grep -wq -- "$user" "$file1" && grep -wq -- "$user" "$file2" ; then
   echo "string avail in both files"
elif grep -wq -- "$user" "$file1" "$file2"; then
   echo "string avail in only one file"
fi
  • grep একাধিক ফাইলে নিদর্শনগুলি অনুসন্ধান করতে পারে, সুতরাং কোনও OR / NOT অপারেটর ব্যবহার করার দরকার নেই।

"-Wq" এবং "-WW" এর মধ্যে প্রতিটি আদেশে কোনও ন্যূনতম পার্থক্য রয়েছে?
মেরেইজ

2
না, তারা উভয়ই গ্রেপ-কে এবং -w বিকল্পগুলি সরবরাহ করে।
গ্লেন জ্যাকম্যান

3
ভেরিয়েবল সম্প্রসারণে কোন উদ্ধৃতি কেন?
ডি বেন নোবল

@ ডি.বেইনকনবল এটি সঠিকভাবে: "$ ব্যবহারকারী" "$ ফাইল 1"?
মেরেইজ

1
@ মেরেয়েস হ্যাঁ এটি সঠিক
ডি বেন নোবল

13

অন্য বিকল্প:

grep -qw -- "$users" "$file1"; in_file1=$?
grep -qw -- "$users" "$file2"; in_file2=$?

case "${in_file1},${in_file2}" in
    0,0) echo found in both files ;;
    0,*) echo only in file1 ;;
    *,0) echo only in file2 ;;
      *) echo in neither file ;;
esac

আরে theচ্ছিক উপায় জন্য আপনাকে ধন্যবাদ। এটি যথেষ্ট ভাল কাজ করে !! আমার অন্য স্ক্রিপ্টে পুরোপুরি কাজ করে।
মেরেইজ

এটা বেশ ভাল ধারণা! সবর্দাই শেখো.
জো

7
n=0

#Or if you have more files to check, you can put your while here. 
grep -qw -- "$users" "$file1" && ((n++))
grep -qw -- "$users" "$file2" && ((n++))

case $n in 
   1) 
       echo "Only one file with the string"
    ;;
   2)
       echo "The two files are with the string"
   ;;
   0)
       echo "No one file with the string"
   ;;
   *)
       echo "Strange..."
   ;;
esac 

দ্রষ্টব্য: ((n++))একটি ksh এক্সটেনশন (এটি দ্বারা সমর্থিত zshএবং bash) পসিক্স shসিনট্যাক্সের n=$((n + 1))পরিবর্তে আপনার প্রয়োজন হবে।


ওহ দুঃখিত, আমি ((n ++)) এর পরিবর্তে $ ((n ++)) টাইপ করছিলাম। ভুলে যান।
লুসিয়ানো অ্যান্ড্রেস মার্টিনি

1
লক্ষ্য করুন n=$((n++))কখনও n এর মান পরিবর্তন করতে হবে কারণ n++হল পোস্টে বৃদ্ধি: এটা ফেরৎ বর্তমান মান n এর, তারপর বাড়তি এন; তারপরে আপনি ভেরিয়েবলটি ফেরত মানতে সেট করলেন যা মূল এন ছিল।
গ্লেন জ্যাকম্যান

আপনি যদি ধরে নিতে পারেন যে আপনার ফাইলের নামগুলিতে নতুন লাইন local IFS=$'\n'; matches=( $(grep -lw "$users" "$file1" "$file2") ), এবং ব্যবহার নেই case "${#matches[@]" in। @ বিগলেন: একাধিক অনুরোধ রক্ষা করতে এই উত্তরটি আপনার উত্তরটিতেও প্রযোজ্য grep। এটি পাইপ grep -l | wc -lকরাও কাজ করবে।
পিটার কর্ডস

@ পিটার যা আলাদা উত্তর আইএমও হিসাবে লেখার জন্য উপযুক্ত হবে।
স্টিফেন কিট

@ স্টেফেনকিট: আমি যাচ্ছিলাম না কারণ আমি স্বেচ্ছাসেবী ফাইল নাম অক্ষরগুলি পরিচালনা করার জন্য বুলেটপ্রুফ উপায় খুঁজে পাইনি। তবে আপনি যেহেতু এটির মূল্যবান বলে মনে করেন, তাই যাইহোক এটি লিখে রেখেছি।
পিটার কর্ডেস

2

যদি আপনার ফাইলের grepনামগুলিতে নিউলাইনগুলি না থাকে তবে আপনি মিলে যাওয়া ফাইলগুলির নাম গ্রেপ প্রিন্ট করে একাধিক অনুরোধ এড়াতে পারবেন এবং ফলাফলগুলি গণনা করতে পারেন।

 local IFS=$'\n'    # inside a function.  Otherwise use some other way to save/restore IFS
 matches=( $(grep -lw "$users" "$file1" "$file2") )

ম্যাচের সংখ্যা "${#matches[@]}"

এখানে ব্যবহারের কোনও উপায় থাকতে পারে grep --null -lwতবে আউটপুটকে কীভাবে পার্স করবেন তা আমি নিশ্চিত নই । বাশের পরিবর্তে ডিলিমিটার var=( array elements )ব্যবহারের উপায় \0নেই \n। হয়তো mapfileবাশের বিল্টিন কি এটা করতে পারে? তবে সম্ভবত তা নয়, কারণ আপনি ডিলিমিটারটি নির্দিষ্ট করেছেন -d string


আপনি করতে পারেন count=$(grep -l | wc -l), তবে তারপরে আপনার দুটি বাহ্যিক প্রক্রিয়া রয়েছে যাতে আপনার পাশাপাশি grepদুটি ফাইল পৃথকভাবে চালানো যেতে পারে । ( grepবনাম wcস্টার্টআপ ওভারহেডের মধ্যে পার্থক্যটি একেবারে পৃথক প্রক্রিয়া শুরু করার জন্য কাঁটাচামক + এক্সিকিউট + ডায়নামিক লিংক স্টাফের সাথে তুলনামূলক কম)।

এছাড়াও, আপনার সাথে কোন ফাইলের মিল রয়েছে wc -lতা খুঁজে পাওয়া যায় না ।


অ্যারেতে প্রাপ্ত ফলাফলগুলির সাথে, এটি ইতিমধ্যে আপনি যা চান তা হতে পারে, বা ঠিক 1 টি মিল আছে, আপনি এটি প্রথম ইনপুট কিনা তা পরীক্ষা করতে পারেন।

local IFS=$'\n'    # inside a function.  Otherwise use some other way to save/restore IFS
matches=( $(grep -lw "$users" "$file1" "$file2") )

# print the matching filenames
[[ -n $matches ]] && printf  'match in %s\n'  "${matches[@]}"

# figure out which input position the name came from, if there's exactly 1.
if [[ "${#matches[@]" -eq 1 ]]; then
    if [[ $matches == "$file1" ]];then
        echo "match in file1"
    else
        echo "match in file2"
    fi
fi

$matchesশর্টহ্যান্ড হ'ল ${matches[0]}, প্রথম অ্যারে উপাদান।


@StephenKitt: আমি বোঝানো -zনা -0, উফ। হ্যাঁ, \0আমি ইতিমধ্যে উত্তরে উল্লিখিত মতো আলাদা করে ফাইলের নামগুলি মুদ্রণের জন্য গ্রেপ পেতে পারি, তবে আপনি কীভাবে এটির বিশ্লেষণ করতে পারেন? আপনি সরাসরি বাশ IFS=$'\0'দিয়ে find -print0স্টাইল আউটপুট দিয়ে সেট করতে পারবেন না বা মূলত অন্য কিছু করতে পারবেন না ।
পিটার কর্ডেস

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

1
mapfile -d $'\0'বিভিন্ন ধরণের কাজ করে তবে নতুন স্থানগুলি স্থানগুলির সাথে প্রতিস্থাপন করে (আমি টুইট করার চেষ্টা করিনি IFS)।
স্টিফেন কিট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.