Shell script exercise questions
Here we mainly collect some shell script exercises to enhance the shell programming capability.
Q1
Analyze the image service logs and rank the logs (the number of visits to each image * The total image size), that is, calculate the total access size of each url.
(Production environment application of this question: this function can be used for IDC websites with high traffic bandwidth. Then, by analyzing which elements of server logs occupy too much traffic, we can optimize or crop the image, compression js and other measures.
Test Data
59.33.26.105--[08/Dec/2010: 15: 43: 56 + 0800] "GET/static/images/photos/2.jpg HTTP/1.1" 200 11299
Three indicators need to be output for this question: [number of visits] [number of visits * size of a single accessed file] [file name (with URL )]
Q2
Calculate the result of 1 + 2 + 3 +... + 100. You can use multiple methods to answer questions.
Q3
Analyze website logs, find out ip addresses that open webpages more than 60 times in one minute (excluding static elements such as images, js, and css), and disable access with iptables. Add crontab to execute the script once every minute.
Q4
The content of teamlist.txt is:
- Name, Team, First Test, Second Test, Third Test
- Tom, Red, 5, 17, 22
- Joe, Green, 3, 14, 22
- Maria, Blue, 6, 18, 21
- Fred, Blue, 2, 15, 23
- Carlos, Red,-1, 15, 24
- Phuong, Green, 7,19, 21
- Enrique, Green, 3, 16, 20
- Nancy, Red, 9, 12, 24
Write an awk script to calculate the average score of each person, the average score of each test and the average score of each team. If a score is negative, it indicates that this person missed the test. This person is excluded from the calculation of the average score before calculation.
The output result is as follows. In the Name List, the name is 10 widths and left alignment (indicating that the %-10 s format is used in printf), while the average value is 7 characters in width, two right-aligned decimal places on the right.
- Name Average
- -----------
- Tom 14.67
- Joe 13.00
- Maria 15.00
- Fred 13.33
- Carlos 19.50
- Phuong 15.67
- Enrique13.00
- Nancy 15.00
- ------------------
- Average for Test 1: 5
- Average for Test 2: 15.75
- Average for Test 3: 22.125
- -------------------
- Average for Red Team: 16
- Average for Blue Team: 14.1667
- Average for Green Team: 13.8889
Q5
Input at least three numeric parameters to the script file and calculate the maximum, minimum, and average values. You must determine whether the input number is sufficient. Otherwise, an alarm is generated. The average value retains two decimal places.
For example, execute./file 3 4 6 5. The output result is as follows:
Max number is: 6
Min number is: 3
Average is: 4.50
Q6
There is a column of numbers as follows:
1st times: 1
2nd times: 2
3rd Times: 3
4th times: 5
5th times: 8
6th times: 13
7th times: 21
8th times: 34
9th times: 55
10th times: 89
11th times: 144
What is the number of write 100 times.
Q7
The file content is as follows:
123abc456
456def123
567abc789
789def567
Required output:
456ABC123
123DEF456
789ABC567
567DEF789
The answer is as follows:
Q1 answer
- Awk '{url [$7] ++; size [$7] + =10 10} END {for (a in url) {print size [a]/1024 "K", url [a], a} 'access. log
Resolution:
Two array URLs and sizes are defined here. The array url is used to calculate the number of visits to a single url, and the array size is used to count the total number of bytes transmitted by a single url. The subsequent for statement reads the element-free link of the array url cyclically, and then prints the total number of bytes transmitted by a single url, the number of accesses, and the corresponding link.
After the data is analyzed, we can use the sort command for sorting.
Q2 answer
Method 1: numerical processing of for... do... done
- Sum = 0
- For (I = 1; I <= 100; I ++ ))
- Do
- (Sum + = $ I ))
- Done
Method 2: for... do... done (fixed loop)
- Sum = 0
- For I in {1 .. 100}
- Do
- (Sum + = $ I ))
- Done
Method 3: while do done (indefinite loop)
- Sum = 0
- I = 1
- While [[$ I-le 100]
- Do
- (Sum + = I ))
- (I ++ ))
- Done
Method 4: until do done (indefinite loop)
- Sum = 0
- I = 1
- Until [[$ I-gt 100]
- Do
- (Sum + = I ))
- (I ++ ))
- Done
Method 5: Build 1 + 2 + 3 .. reuse bc computing
- Seq 100 | tr "\ n" "+" | sed's/+ $/\ n/'| bc
Q3 answer
- Now = 'date + % H % M % s'
- Ago = 'date-d "1 minute ago" + % H % M % s'
- Badip = 'Tail-n 10000 access. log | egrep-v "\. (gif | jpg | jpeg | png | css | js)" | awk'
- BEGIN {
- N = '"$ now "'
- A = '"$ ago "'
- FS = "[:] +"
- }
- {
- T = $5 $6 $7
- If (t> = a & t <= n ){
- Num [$1] ++
- }
- }
- END {
- For (ip in num ){
- If (num [ip]> 60 ){
- Print ip
- }
- }
- }
- ''
- If [! -Z "$ badip"]; then
- For ip in $ badip;
- Do
- If test-z "'/sbin/iptables-nL | grep $ ip'"; then
- /Sbin/iptables-I INPUT-s $ ip-j DROP
- Fi
- Done
- Fi
Resolution:
1. Define the two variables now and ago, respectively, the current time, the time one minute ago, in the format of % H % M % S.
2. Obtain the last 10 thousand lines of the log (which can be modified based on the traffic) and use egrep to exclude images and other files.
3. Call the two variables set in step 1 in the awin Statement of awk.
4. Use the variables t, a, and n to determine and retrieve logs within one minute, and use the array num to count the number of times ip addresses appear.
5. In the END statement, determine whether the number of times the ip address appears exceeds 60. If the number exceeds 60, the ip address is output to the variable badip.
6. for loop to get each ip in the variable badip, and add iptables rules to prohibit access.
Q4 answer
- Awk-F, 'in in {
- Printf "%-10 s % s \ n", "Name", "Average"
- Printf "%-10 s % s \ n ","----","-------"
- }
- NR> 1 {
- Sum = 0
- N = 0
- For (I = 3; I <= 5; I ++ ){
- If ($ I> 0 ){
- N ++
- Sum = sum + $ I
- Testcount [I-2] ++
- Testtotal [I-2] + = $ I
- Teamcount [$2] ++
- Teamtotal [$2] + = $ I
- }
- }
- Printf "%-10 s % 7.2f \ n", $1, sum/n
- }
- END {
- Print "------------------"
- For (j = 1; j <= 3; j ++ ){
- Print "Average for Test" j ":" testtotal [j]/testcount [j]
- }
- Print "-------------------"
- For (t in teamcount ){
- Print "Average for" t "Team:" teamtotal [t]/teamcount [t]
- }
- } 'Teamlist.txt
Resolution:
1. Two columns of the awk BEGIN statement output table.
2. NR> 1 indicates that only data starting from the second row is processed.
3. sum = 0, n = 0. initialize the total scores of the three tests and the number of participants.
4. Define a for loop and process the test data three times in a loop.
5. The test is performed only when the score is greater than 0.
6. to calculate the average score of each person, use variable n to record the number of tests and variable sum to accumulate the scores three times. Then, use printf to format and output the average score of each person; in order to calculate the average score for each of the three tests, an array of testcount records the number of participants in a test using the I-2 as an index (I .e. the I-2 test, the array testtotal records the total score of a test. to calculate the average score of each group, the group name in the second column is used as the index. The array teamcount records the number of participants in a group, array teamtotal records the total scores of a group.
7. Use two for loop statements in the END statement to output the average scores of each test and each group of tests respectively.
Q5 answer
Method 1: Use the awk command to calculate
- If ["$ #"-lt 2]; then
- Echo "parameter must be at least 3 ."
- Exit 1
- Fi
- Echo "$ @" | awk'
- BEGIN {
- RS = "+"
- }
- {
- Sum + = $0
- }
- NR = 1 {
- Max = $1; min = $1
- Next
- }
- $1> max {
- Max = $1
- }
- $1 <min {
- Min = $1
- }
- END {
- Printf "max number is: % s \ n", max
- Printf "min number is: % s \ n", min
- Printf "average is: %. 2f \ n", sum/NR
- }'
Resolution:
1. Determine whether there are more than two parameters. Otherwise, exit the script.
2. input all parameters in the MPs queue to the awk and set the rs of the awk to a space.
3. sum + = $0, calculate and.
4. NR = 1 {} First assigns the first parameter to max and min to prevent calculation errors when all numbers are negative.
5. $1> max {} checks whether the number is larger than the current number of the variable max. If yes, assign $1 to max so that the variable can maintain the maximum value at all times.
6. $1 7. Print the maximum and minimum values. The average value is sum/NR.
Method 2: Use commands such as while and shift
- N = $ #
- If ["$ n"-lt 2]; then
- Echo "parameter must be at least 3 ."
- Exit 1
- Fi
- Max = $1
- Min = $1
- Sum = $1
- Shift
- While [$ #-gt 0]
- Do
- (Sum + = $1 ))
- [$1-gt $ max] & max = $1
- [$1-lt $ min] & min = $1
- Shift
- Done
- Echo "max number is:" $ max
- Echo "min number is:" $ min
- Ave = 'echo "scale = 2; $ sum/$ n" | bc'
- Echo "average is:" $ ave
Resolution:
1. Assign the number of parameters to Variable n.
2. determine the number of parameters
3. Assign the first number to the variables max, min, and sum, and shift the parameter to the left, that is, change the previous $2 to $1, and the variable $ # Minus 1.
4. while and shift commands are used to read parameters in sequence and determine the maximum and minimum values.
5. the maximum and minimum values of echo output are calculated in bc, and the scale = 2 is defined to keep two decimal places.
Q6 answer
- A [1] = 1
- A [2] = 2
- I = 3
- While [$ I-le 100]
- Do
- (A [$ I] =$ {a [$ I-1]} + $ {a [$ I-2]})
- (I ++ ))
- Done
- Echo $ {a [100]}
Q7 answer
- Sed's/\ ([0-9] * \) \ ([a-z] * \) \ ([0-9] * \) /\ 3 \ U \ 2 \ E \ 1/'file
Resolution:
1. ([0-9] *) match consecutive numbers and ([a-z] *) match consecutive lowercase letters.
2. "123" indicates the reference to the content of the brackets, and "U2E" indicates converting the 2 letters into uppercase letters.