পাওয়ারশেলের একটি অ্যারের সমস্ত বস্তুর উপর একটি বৈশিষ্ট্যের মান নির্বাচন করুন


134

ধরা যাক আমাদের কাছে বস্তুর $ অবজেক্টগুলির একটি অ্যারে রয়েছে। ধরা যাক এই বিষয়গুলির একটি "নাম" সম্পত্তি রয়েছে।

এটাই আমি করতে চাই

 $results = @()
 $objects | %{ $results += $_.Name }

এটি কাজ করে, তবে এটি আরও ভাল উপায়ে করা যায়?

আমি যদি এমন কিছু করি:

 $results = objects | select Name

$resultsএকটি নাম সম্পত্তি থাকা অবজেক্টগুলির একটি অ্যারে। আমি চাই $ ফলাফলগুলিতে নামের একটি অ্যারে থাকে।

একটি ভাল উপায় আছে কি?


4
শুধু সম্পূর্ণতার জন্য, আপনি আপনার মূল কোড থেকে, "+ =" দূর করতে পারবে, যাতে foreach শুধুমাত্র নির্বাচন নাম: $results = @($objects | %{ $_.Name })। এটি অনেক সময় কমান্ড লাইনে টাইপ করা আরও সুবিধাজনক হতে পারে, যদিও আমি মনে করি স্কটের উত্তর সাধারণত ভাল।
সম্রাট এক্স এলআইআই

1
@ এমপায়ার এক্স এলআই: ভাল পয়েন্ট, এবং পিএসভি 3 + তে আপনি এটিকে আরও সহজ করতে পারবেন:$objects | % Name
এমকিলেমেন্ট 0

উত্তর:


212

আমি মনে করি আপনি ExpandPropertyপ্যারামিটারটি ব্যবহার করতে সক্ষম হতে পারেন Select-Object

উদাহরণস্বরূপ, বর্তমান ডিরেক্টরিটির তালিকা পেতে এবং নাম বৈশিষ্ট্যটি প্রদর্শিত করতে কেবল নিম্নলিখিতটি করা উচিত:

ls | select -Property Name

এটি এখনও ডিরেক্টরীআইএনফো বা ফাইলআইনফোর অবজেক্টগুলিকে ফিরিয়ে দিচ্ছে। আপনি সর্বদা পাইপলাইনটির মাধ্যমে আগত ধরণটি গেট-সদস্য (ওরফে gm) তে পাইপ দিয়ে পরীক্ষা করতে পারেন ।

ls | select -Property Name | gm

সুতরাং, আপনি যে ধরণের সম্পত্তিটির দিকে তাকিয়ে রয়েছেন তা হ'ল বস্তুটি প্রসারিত করতে আপনি নিম্নলিখিতগুলি করতে পারেন:

ls | select -ExpandProperty Name

আপনার ক্ষেত্রে, আপনি কেবল ভেরিয়েবলের জন্য একটি স্ট্রিংয়ের অ্যারে হতে চলতে নিম্নলিখিতগুলি করতে পারেন, যেখানে স্ট্রিংগুলি নাম বৈশিষ্ট্য:

$objects = ls | select -ExpandProperty Name

73

আরও সহজ সমাধান হিসাবে আপনি কেবল এটি ব্যবহার করতে পারেন:

$results = $objects.Name

এতে $resultsথাকা উপাদানগুলির সমস্ত 'নাম' সম্পত্তি মানগুলির একটি অ্যারে পূরণ করা উচিত $objects


মনে রাখবেন এটি এতে কাজ করে না Exchange Management Shell। এক্সচেঞ্জ ব্যবহার করার সময় আমাদের ব্যবহার করা দরকার$objects | select -Property Propname, OtherPropname
বাসি

2
@ বাসি: অ্যারে হিসাবে সদস্যদের মানগুলি পেতে সংগ্রহ স্তরে একটি সম্পত্তি অ্যাক্সেসকে সদস্য সংখ্যা বলা হয় এবং এটি একটি PSv3 + বৈশিষ্ট্য ; সম্ভবত, আপনার এক্সচেঞ্জ ম্যানেজমেন্ট শেলটি PSv2।
mklement0

32

কোন পদ্ধতির এবং একটি পারফরম্যান্স তুলনা কখন ব্যবহার করবেন তার দিকনির্দেশনা সহ পূর্ববর্তী, সহায়ক উত্তরগুলির পরিপূরক করতে ।

  • পাইপলাইনের বাইরে , ব্যবহার করুন (PSv3 +):

     বস্তু নাম
    যেমনটি রাগান্দাক্কের উত্তরে প্রদর্শিত হয়েছে , যা উভয় বাক্যগতভাবেই সহজ এবং আরও দ্রুত

    • অ্যারে হিসাবে সদস্যদের মানগুলি পেতে সংগ্রহ স্তরে কোনও সম্পত্তির অ্যাক্সেসকে সদস্য সংখ্যা বলা হয় এবং এটি একটি PSv3 + বৈশিষ্ট্য।
    • বিকল্পভাবে, পিএসভি 2 - তে , foreach বিবৃতিটি ব্যবহার করুন , যার আউটপুট আপনি সরাসরি কোনও ভেরিয়েবলকেও নির্ধারণ করতে পারেন:
      $ ফলাফল = পূর্বাচ ($ অবজেক্টে $ অবজেক্ট) $ $ আপজেক্ট.নাম}
    • ট্রেড অফস :
      • ইনপুট সংগ্রহ এবং আউটপুট অ্যারে উভয়ই পুরো মেমরির সাথে মাপসই করা উচিত ।
      • যদি ইনপুট সংগ্রহটি নিজেই কোনও কমান্ডের (পাইপলাইন) ফলাফল (উদাহরণস্বরূপ, (Get-ChildItem).Name) হয় তবে ফলাফলটি অ্যারের উপাদানগুলি অ্যাক্সেস করার আগে সেই কমান্ডটি প্রথমে সমাপ্ত হতে হবে।
  • একটি পাইপলাইনে যেখানে ফলাফলটি আরও প্রক্রিয়া করা উচিত বা ফলাফল সামগ্রিকভাবে মেমরির সাথে খাপ খায় না, সেখানে ব্যবহার করুন:

    $ অবজেক্টস | সিলেক্ট-অবজেক্ট- এক্সপ্যানডপ্রোপার্টি নাম

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

জন্য ছোট ইনপুট সংগ্রহ (অ্যারে), আপনি সম্ভবত পার্থক্য লক্ষ্য হবে , এবং, বিশেষ করে কমান্ড লাইন মাঝে মাঝে কমান্ড টাইপ করতে সক্ষম হচ্ছে সহজে আরো গুরুত্বপূর্ণ।


এখানে একটি সহজ-ধরণের বিকল্প রয়েছে , যা তবে ধীরতম পদ্ধতি ; এটি অপারেশন স্টেটমেন্ট নামে পরিচিত সরলীকৃত ForEach-Objectসিনট্যাক্স ব্যবহার করে (আবার, PSv3 +):; উদাহরণস্বরূপ, নিম্নলিখিত PSv3 + সমাধানটি একটি বিদ্যমান কমান্ডে যুক্ত করা সহজ:

$objects | % Name      # short for: $objects | ForEach-Object -Process { $_.Name }

সম্পূর্ণতার স্বার্থে জন্য: সামান্য বিখ্যাত PSv4 + + .ForEach() অ্যারের পদ্ধতি , আরো comprehensivel আলোচনা এই নিবন্ধটি হয় এখনও অন্য বিকল্প :

# By property name (string):
$objects.ForEach('Name')

# By script block (more flexibility; like ForEach-Object)
$objects.ForEach({ $_.Name })
  • এই পদ্ধতির সদস্য সংখ্যা গণনার অনুরূপ , একই ট্রেডঅফগুলি সহ, পাইপলাইন যুক্তি প্রয়োগ করা হয় নি ; এটি সামান্য ধীর , যদিও পাইপলাইনের তুলনায় লক্ষণীয়ভাবে দ্রুত।

  • নাম ( স্ট্রিং আর্গুমেন্ট) দ্বারা একক সম্পত্তির মান আহরণের জন্য , এই সমাধানটি সদস্য গণনার সমতুল্য (যদিও পরবর্তীটি সিন্টেক্সটিক্যালি সহজ)।

  • স্ক্রিপ্ট-ব্লক বৈকল্পিক , নির্বিচারে পারবেন রূপান্তরের ; এটি একটি দ্রুত - সমস্ত-একবারে-মেমরি-একবারে - পাইপলাইন ভিত্তিক ForEach-Object সেমিডলেট ( %) এর বিকল্প


বিভিন্ন পদ্ধতির কর্মক্ষমতা তুলনা করা

এখানে 10 টির জুড়ে গড়ে ওঠা বিভিন্ন বস্তুর ইনপুট সংগ্রহের ভিত্তিতে বিভিন্ন পদ্ধতির জন্য নমুনার সময় দেওয়া আছে ; নিখুঁত সংখ্যাগুলি গুরুত্বপূর্ণ নয় এবং অনেকগুলি কারণের উপর নির্ভর করে পরিবর্তিত হয় তবে এটি আপনাকে আপেক্ষিক পারফরম্যান্সের ধারণা দেয় (সময়গুলি একক-কোর উইন্ডোজ 10 ভিএম থেকে আসে:10,000

গুরুত্বপূর্ণ

  • ইনপুট অবজেক্টগুলি নিয়মিত .NET প্রকারের উদাহরণ (যেমন, আউটপুট হিসাবে বাই Get-ChildItem) বা [pscustomobject]উদাহরণস্বরূপ (যেমন, আউটপুট হিসাবে ) এর উপর ভিত্তি করে আপেক্ষিক পারফরম্যান্স পরিবর্তিত হয় Convert-FromCsv
    কারণটি হ'ল [pscustomobject]সম্পত্তিগুলি গতিশীলভাবে পাওয়ারশেল দ্বারা পরিচালিত হয় এবং এটি নিয়মিত (স্ট্যাটিক্যালি সংজ্ঞায়িত) নিয়মিত। নেট প্রকারের নিয়মিত বৈশিষ্ট্যের চেয়ে আরও দ্রুত এগুলি অ্যাক্সেস করতে পারে। উভয় পরিস্থিতিতে নীচে আচ্ছাদিত করা হয়।

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

  • বংশবৃদ্ধির %জন্য , উপনামটি ForEach-Objectসেমিডলেট জন্য ব্যবহৃত হয় ।

নিয়মিত। নেট প্রকার এবং [pscustomobject]ইনপুট উভয়ের জন্যই সাধারণ সিদ্ধান্তসমূহ প্রযোজ্য :

  • সদস্য-গণনা ( $collection.Name) এবং foreach ($obj in $collection)সমাধানগুলি দ্রুততম পাইপলাইন-ভিত্তিক সমাধানের চেয়ে 10 বা তত বেশি গতির একটি উপাদান দ্বারা দ্রুততম হয় the

  • আশ্চর্যজনকভাবে, এর থেকে % Nameআরও খারাপ সম্পাদন করে % { $_.Name }- এই গিটহাব ইস্যুটি দেখুন

  • পাওয়ারশেল কোর এখানে নিয়মিত উইন্ডোজ পাওয়ারশেলকে ছাড়িয়ে যায়।

সঙ্গে সময় নিয়মিত .NET ধরনের :

  • পাওয়ারশেল কোর v7.0.0-প্রাকদর্শন 3
Factor Command                                       Secs (10-run avg.)
------ -------                                       ------------------
1.00   $objects.Name                                 0.005
1.06   foreach($o in $objects) { $o.Name }           0.005
6.25   $objects.ForEach('Name')                      0.028
10.22  $objects.ForEach({ $_.Name })                 0.046
17.52  $objects | % { $_.Name }                      0.079
30.97  $objects | Select-Object -ExpandProperty Name 0.140
32.76  $objects | % Name                             0.148
  • উইন্ডোজ পাওয়ারশেল v5.1.18362.145
Comparing property-value extraction methods with 10000 input objects, averaged over 10 runs...

Factor Command                                       Secs (10-run avg.)
------ -------                                       ------------------
1.00   $objects.Name                                 0.012
1.32   foreach($o in $objects) { $o.Name }           0.015
9.07   $objects.ForEach({ $_.Name })                 0.105
10.30  $objects.ForEach('Name')                      0.119
12.70  $objects | % { $_.Name }                      0.147
27.04  $objects | % Name                             0.312
29.70  $objects | Select-Object -ExpandProperty Name 0.343

উপসংহার:

  • পাওয়ারশেল কোরে , .ForEach('Name')পরিষ্কারভাবে ছাড়িয়ে যায় .ForEach({ $_.Name })। উইন্ডোজ পাওয়ারশেলে, কৌতূহলজনকভাবে, আধুনিকগুলি কেবলমাত্র সামান্য হলেও তত দ্রুত।

সঙ্গে সময় [pscustomobject]দৃষ্টান্ত :

  • পাওয়ারশেল কোর v7.0.0-প্রাকদর্শন 3
Factor Command                                       Secs (10-run avg.)
------ -------                                       ------------------
1.00   $objects.Name                                 0.006
1.11   foreach($o in $objects) { $o.Name }           0.007
1.52   $objects.ForEach('Name')                      0.009
6.11   $objects.ForEach({ $_.Name })                 0.038
9.47   $objects | Select-Object -ExpandProperty Name 0.058
10.29  $objects | % { $_.Name }                      0.063
29.77  $objects | % Name                             0.184
  • উইন্ডোজ পাওয়ারশেল v5.1.18362.145
Factor Command                                       Secs (10-run avg.)
------ -------                                       ------------------
1.00   $objects.Name                                 0.008
1.14   foreach($o in $objects) { $o.Name }           0.009
1.76   $objects.ForEach('Name')                      0.015
10.36  $objects | Select-Object -ExpandProperty Name 0.085
11.18  $objects.ForEach({ $_.Name })                 0.092
16.79  $objects | % { $_.Name }                      0.138
61.14  $objects | % Name                             0.503

উপসংহার:

  • কীভাবে [pscustomobject]ইনপুট .ForEach('Name')দিয়ে স্ক্রিপ্ট-ব্লক ভিত্তিক বৈকল্পিককে কার্যকরভাবে চিহ্নিত করে .ForEach({ $_.Name })

  • একইভাবে, [pscustomobject]ইনপুটটি পাইপলাইন-ভিত্তিক Select-Object -ExpandProperty Nameদ্রুততর করে তোলে , উইন্ডোজ পাওয়ারশেলের কার্যত ভারসাম্যহীন .ForEach({ $_.Name }), তবে পাওয়ারশেল কোরটিতে এখনও প্রায় 50% ধীর গতি রয়েছে।

  • সংক্ষেপে বলতে গেলে: এর বিজোড় ব্যতিক্রম সঙ্গে % Nameসঙ্গে [pscustomobject]বৈশিষ্ট্য উল্লেখ স্ট্রিং ভিত্তিক পদ্ধতি scriptblock ভিত্তিক বেশী সুখ্যাতি।


পরীক্ষার জন্য উত্স কোড :

বিঃদ্রঃ:

  • এই পরীক্ষাগুলি চালানোর জন্য এই গিস্টTime-Command থেকে ফাংশনটি ডাউনলোড করুন ।

  • পরিবর্তে উদাহরণগুলির সাথে পরিমাপ $useCustomObjectInputকরতে সেট করুন ।$true[pscustomobject]

$count = 1e4 # max. input object count == 10,000
$runs  = 10  # number of runs to average 

# Note: Using [pscustomobject] instances rather than instances of 
#       regular .NET types changes the performance characteristics.
# Set this to $true to test with [pscustomobject] instances below.
$useCustomObjectInput = $false

# Create sample input objects.
if ($useCustomObjectInput) {
  # Use [pscustomobject] instances.
  $objects = 1..$count | % { [pscustomobject] @{ Name = "$foobar_$_"; Other1 = 1; Other2 = 2; Other3 = 3; Other4 = 4 } }
} else {
  # Use instances of a regular .NET type.
  # Note: The actual count of files and folders in your home dir. tree
  #       may be less than $count
  $objects = Get-ChildItem -Recurse $HOME | Select-Object -First $count
}

Write-Host "Comparing property-value extraction methods with $($objects.Count) input objects, averaged over $runs runs..."

# An array of script blocks with the various approaches.
$approaches = { $objects | Select-Object -ExpandProperty Name },
              { $objects | % Name },
              { $objects | % { $_.Name } },
              { $objects.ForEach('Name') },
              { $objects.ForEach({ $_.Name }) },
              { $objects.Name },
              { foreach($o in $objects) { $o.Name } }

# Time the approaches and sort them by execution time (fastest first):
Time-Command $approaches -Count $runs | Select Factor, Command, Secs*

1

সাবধানতা, সদস্য সংখ্যা কেবল তখনই কাজ করে যদি সংগ্রহে নিজেই একই নামের সদস্য না থাকে। সুতরাং আপনার যদি ফাইলআইনফো অবজেক্টগুলির একটি অ্যারে থাকে তবে আপনি ব্যবহার করে ফাইলের দৈর্ঘ্যের একটি অ্যারে পেতে পারেন না

 $files.length # evaluates to array length

এবং আপনি "ভাল সুস্পষ্টভাবে" বলার আগে এটি বিবেচনা করুন। আপনার যদি সামর্থ্যের সম্পত্তি সহ কোনও বস্তুর অ্যারে থাকে

 $objarr.capacity

হায় কাজ জরিমানা যদি না $ objarr আসলে ছিল না একটি [এরে] কিন্তু, উদাহরণস্বরূপ, একটি [ArrayList]। সুতরাং সদস্য সংখ্যা ব্যবহার করার আগে আপনাকে আপনার সংগ্রহে থাকা কালো বাক্সের ভিতরে দেখতে হবে।

(মডারেটরদের কাছে দ্রষ্টব্য: রাগান্দাক্কের উত্তরের উপর এটি একটি মন্তব্য হওয়া উচিত তবে আমার এখনও যথেষ্ট খ্যাতি নেই))


এটি একটি ভাল পয়েন্ট; এই গিটহাব বৈশিষ্ট্যটির অনুরোধটি সদস্যগণের জন্য পৃথক সিনট্যাক্স চেয়েছে। নাম সংঘর্ষগুলির জন্য .ForEach()$files.ForEach('Length')
কার্যপ্রণালীটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.