বিভিন্ন ডিরেক্টরি এবং ফাইল অ্যাক্সেসের বিকল্পগুলির সাথে স্ক্রিপ্ট তৈরি করা


12

আমি দীর্ঘদিন ধরে একটি স্ক্রিপ্ট লেখার জন্য সংগ্রাম করছি যার মধ্যে 2 টি যুক্তি রয়েছে, 1 একটি বছর নির্বাচন করতে বলছে এবং 2 নির্বাচন করতে বলছে যদি আমি সম্পর্কিত ফাইলগুলি থেকে সর্বনিম্ন, সর্বোচ্চ, গড় বা সমস্ত শেষ লাইন হিসাবে দেখানো চাই নির্বাচিত বছর।

মূলত, আমার একটি ডিরেক্টরি রয়েছে যা বিভিন্ন বছরের উপ-ডিরেক্টরিগুলি অন্তর্ভুক্ত করে (2000, 2001, 2002 ইত্যাদি) সেই ডিরেক্টরিগুলিতে মাস এবং দিনের জন্য উপ-ডিরেক্টরি রয়েছে যা (ক) ফাইল (গুলি) জনসংখ্যা সম্পর্কে তথ্য দেয় (যদিও আসল তথ্য নয়) শেষ লাইন হিসাবে শহরগুলি। এটি ডিরেক্টরি গাছের একটি অংশ:

.
|-- 2000
|   |-- 01
|   |   `-- 18
|   |       `-- ff_1177818640
|   |-- 02
|   |   |-- 02
|   |   |   `-- ff_1669027271
|   |   |-- 03
|   |   |   `-- ff_234075290
|   |   |-- 10
|   |   |   `-- ff_1584524530
|   |   |-- 14
|   |   |   `-- ff_113807345
|   |   `-- 17
|   |       `-- ff_1452228827
|   |-- 03
|   |   |-- 06
|   |   |   `-- ff_58914249
|   |   `-- 11
|   |       `-- ff_2828212321
|   |-- 04
|   |   `-- 17
|   |       `-- ff_302131884
|   |-- 06
|   |   `-- 13
|   |       `-- ff_2175615745
|   |-- 07
|   |   |-- 07
|   |   |   `-- ff_918426998
|   |   `-- 24
|   |       `-- ff_2808316425
|   |-- 08
|   |   `-- 27
|   |       `-- ff_1449825497
|   |-- 09
|   |   `-- 19
|   |       `-- ff_110255856
|   `-- 12
|       `-- 08
|           `-- ff_1621190
|-- 2001
|   |-- 03
|   |   `-- 21
|   |       `-- ff_517010375
|   |-- 05
|   |   `-- 27
|   |       `-- ff_1458621098
|   |-- 06
|   |   |-- 07
|   |   |   `-- ff_155853916
|   |   |-- 25
|   |   |   |-- ff_2382312387
|   |   |   `-- ff_270731174
|   |   `-- 29
|   |       `-- ff_3228522859
|   |-- 07
|   |   `-- 28
|   |       `-- ff_3215021752
|   |-- 09
|   |   `-- 24
|   |       `-- ff_1080314364
|   `-- 11
|       `-- 24
|           `-- ff_2313722442

সমস্ত ফাইল একইভাবে ফরম্যাট করা হয়:

2019-04-03
Wednesday
Newcastle-upon-Tyne
255362

আমার কোন বছরটি প্রয়োজন (সেই ডিরেক্টরিটি নির্বাচন করে) জিজ্ঞাসা করার জন্য আমাকে একটি স্ক্রিপ্ট লিখতে হবে এবং তারপরে জিজ্ঞাসা করতে হবে যে আমি গড়, সর্বনিম্ন, সর্বোচ্চ বা উপরের সমস্তটি জনসংখ্যার জন্য প্রদর্শন করতে চাই (যা ফাইলগুলির শেষ লাইন)।

আমার এ পর্যন্ত যা আছে:

#!/bin/bash

function min () {
    echo $(sort -n populations | head -1)
}

function max () {
    echo $(sort -n populations | tail -1)
}

function avg () {
    count=0
    sum=0
    while read line ; do
        num='echo ${line#* }'
        sum='expr $sum + $num'
        count='expr $count + 1'
    done < populations
    avg='expr $sum / $count'
    echo $avg
}

echo "Please enter the year: "
read s1
echo "
        Enter an option:
        1. Minimum
        2. Maximum
        3. Average
        4. All"
read s2
#echo $s2
for file in $(find ~/filesToSort/$s1 -type f) ; do
    tail -1 $file >> populations
done
echo $(cat populations)
#min
#max
#avg
rm populations

এটি আমাকে ডিরেক্টরি বাছতে দেয়, তবে আমার যে উত্তরগুলি প্রয়োজন তা আমাকে দেয় না, কেবল আমার ফাইলগুলির শেষ লাইনগুলিকে ছড়িয়ে দেয়।


সুতরাং আপনি 'জনসংখ্যা' ফাইলটিতে সঞ্চিত সংখ্যাগুলি থেকে গণিত করতে চান?
cmak.fr

উত্তর:


7

আমি যদি এটি ব্যাশে বাস্তবায়ন করতাম তবে আমি নিম্নলিখিতটি করতাম। আমি এ বিষয়ে তেমন মন্তব্য করব না: যদিও নির্দিষ্ট প্রশ্ন জিজ্ঞাসা করতে নির্দ্বিধায় - কোন নির্দিষ্ট কমান্ড কীভাবে কাজ করে তা আপনি যদি জানেন না তবে প্রথমে ব্যাশ ম্যান পৃষ্ঠাটি পরীক্ষা করুন।

#!/bin/bash

# read the population from all the files
# map the filename to it's population figure
declare -A population
while IFS= read -d '' -r filename; do
    population["$filename"]=$(tail -1 "$filename")
done < <(find . -type f -print0)

# prompt the user for the year
read -rp "What year? " year

# find the relevant files for that year
year_files=()
for filename in "${!population[@]}"; do
    [[ $filename == ./"$year"/* ]] && year_files+=("$filename")
done
if [[ "${#year_files[@]}" -eq 0 ]]; then
    echo "No files for year '$year'"
    exit 1
fi

PS3="Select a function to calculate: "
select func in minimum maximum average quit; do
    case $func in
        minimum)
            min=${population[${year_files[0]}]}
            for file in "${year_files[@]}"; do
                if (( min > ${population[$file]} )); then
                    min=${population[$file]}
                fi
            done
            echo "Minimum for $year is $min"
            ;;
        maximum)
            max=${population[${year_files[0]}]}
            for file in "${year_files[@]}"; do
                if (( max < ${population[$file]} )); then
                    max=${population[$file]}
                fi
            done
            echo "Maximum for $year is $max"
            ;;
        average)
            count=0 sum=0
            for file in "${year_files[@]}"; do
                (( sum += ${population[$file]} ))
                (( count++ ))
            done
            echo "Average for $year is $(( sum / count ))"
            ;;
        quit) exit ;;
    esac
done

"অল" হিসাবে অন্য একটি বিকল্প বিকল্প থাকতে হবে
সিসাব

5

আমি একটি সাধারণ awkস্ক্রিপ্ট লিখি যা আপনি যা করছেন ঠিক তেমন করে:

# read 'year' & 'option' from user
# or you can pass as argument to the command $1<-->$year & $2<-->$option

find /path/to/$year -type f -exec \
    awk -v select=$option '
        FNR==4 { sum+=$0; avg=sum/++count; 
                 max=(max>=$0?max:$0);
                 if (count==1) min=$0;
        }
        count>1 { min=(min<=$0?min:$0);
        }
    END{ stats=min","max","avg","min"\n"max"\n"avg;
         split(stats, to_print,",");
         print to_print[select];
    }' {} +

ইনলাইন ব্যাখ্যা:

# read 'year' & 'option' from user
# or you can pass as argument to the command $1<-->$year & $2<-->$option

find /path/to/$year -type f -exec \
# find all files under "/path/to/$year". $year will be substitute with the value 
# of 'year' variable read from user-input or replace it with '$1' as first argument to the command

    awk -v select=$option '
    # read the value of shell 'option' variable into an awk 'select' variable 
    # replace with '$2' as argument to the command

        FNR==4 { sum+=$0; avg=sum/++count;
        # if it's 4th line of each input file, sum-up the value into 'sum' variable
        # and calculate the 'avg' too when 'count' will increment once each 4th record in a file is read

                 max=(max>=$0?max:$0);
                 # its a Ternary operator (condition?if-true:if-false) and finding maximum value

                 if (count==1) min=$0;
                 # keep the first file's 4th line's value as minimum. you could use `NR==4` instead
        }
        count>1 { min=(min<=$0?min:$0);
        # same as max, update the 'min' if value in current file is smaller than 'min' in previous file
        }
    END{ stats=min","max","avg","min"\n"max"\n"avg;
    # saving all variables' value into single variable with comma separated. I used <min"\n"max"\n"avg> as 
    # fourth element which we will use it as "All" option that each separated with newlines.

         split(stats, to_print, ",");
         # building an array called 'to_print' from 'stats' variable above with comma separator to distinguish 
         # the elements from each other.

         print to_print[select];
         # this will print the element which user-input as an option.
         # if input 1: will print 'min'
         # if input 2: will print 'max'
         # if input 3: will print 'avg'
         # if input 4: will print 'min' \n 'max' '\n' avg
    }' {} +

0

লিখিত হিসাবে, স্ক্রিপ্ট জনসংখ্যা মুদ্রণ ব্যতীত কিছুই করবে না কারণ গড় ইত্যাদি মন্তব্য করা হয়।

গড় গণনা করতে, এই জনসংখ্যা অবশ্যই এমন কিছু সহ औसत () ফাংশনে প্রেরণ করতে হবে ...

echo "$(cat populations | avg)"

অনুরূপ লাইনগুলি মিনিট () এবং সর্বোচ্চ () এর জন্য যুক্ত করা হবে।

আপনি caseউপযুক্ত ফাংশন (গুলি) কল করতে একটি বিবৃতি ব্যবহার করতে পারেন ...

  :
done
#
case s2
  1|4) echo "$(cat populations | min)" ;;&
  2|4) echo "$(cat populations | max)" ;;&
  3|4) echo "$(cat populations | avg)";;
esac
#
rm populations

1|4) echo ...যদি পারেন 1 বা 4 প্রবেশ প্রতিধ্বনি চালানোর কারণ। সুতরাং, 4 টি প্রবেশ করানো হলে সমস্ত 3 কার্যকর করা হবে।


1
পার্লডাক - আপনি সঠিক (তবে এটি ';; &')। সংশোধন। ধন্যবাদ।
ডকসালভাজার

0

সমস্ত উত্তরের জন্য ধন্যবাদ, আমি এখানে দিয়ে শেষ করেছি কি এখানে:

#!/bin/bash
### Returns the minimum value by sorting the population file's data and displaying the top line.
 function min () {
         echo "Minimum Population: "$(sort -n populations | head -1)
 }
  ### Returns the maximum value by sorting the population file's data and displaying the bottom line.
 function max () {
         echo "Maximum Population: "$(sort -n populations | tail -1)
 }
  ### A function to return the average number of population.
 function avg () {
         count=0
         sum=0
         while read line ; do
                 num=`echo ${line#* }`
                 sum=`expr $sum + $num`
                 count=`expr $count + 1`
         done < populations
         avg=`expr $sum / $count`
         echo "Average Population: "$avg
 }
  ### Advises what the script does and asks for an imput of a year.
 echo "
         ######################
         # Population adviser #
         ######################
          Please enter the year: "
 read s1
  ### If statement checking the year entered is available, if not then the user is informed of invalid selection and program terminates.
 if [[ $s1 -ge 2000 && $s1 -le 2019 && $s1 -ne 2009 ]] ; then
         continue 2>/dev/null
 else
         echo "The year you entered is not valid, program terminating"
         exit
 fi
  ### Prompts user for input
 echo "
         Enter an option:
         1. Minimum
         2. Maximum
         3. Average
         4. All
  -----(minimum) (maximum) (average) (all)-----
 "
 read s2
  ### Loops through all files within the given directory path and appends the population of each file to the population list
 for file in $(find ~/filesToSort/$s1 -type f) ; do
         tail -1 $file >> populations
 done
  ### If statement to validate user input and then use the function(s) required
 if [ "$s2" == "minimum" ] ; then
         min
 elif [ "$s2" == "maximum" ] ; then
         max
 elif [ "$s2" == "average" ] ; then
         avg
 elif [ "$s2" == "all" ] ; then
         min
         max
         avg
 else
         echo "The option you chose is invalid, program terminating"
         rm populations
         exit
 fi
  ### Removes "populations" file upon completion
 rm populations

সংখ্যার পরিবর্তে বিকল্পটি পছন্দ করার সময় (1-4) পরিবর্তে একটি শব্দ লিখতে হবে, যা আমি ঘৃণা করি তবে এটি এইভাবে করতে বলা হয়েছিল।

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