1 00:00:06,810 --> 00:00:08,520 - Another common element in a script 2 00:00:08,520 --> 00:00:10,710 is the pattern-matching operator. 3 00:00:10,710 --> 00:00:11,970 The pattern-matching operator 4 00:00:11,970 --> 00:00:14,340 is all about cleaning up strings. 5 00:00:14,340 --> 00:00:16,470 So if a user provides information, 6 00:00:16,470 --> 00:00:18,390 but there's too much information 7 00:00:18,390 --> 00:00:20,430 and you only need to have a part of it, 8 00:00:20,430 --> 00:00:23,430 then pattern-matching operator is what you are going to use. 9 00:00:24,480 --> 00:00:25,920 So how does it work? 10 00:00:25,920 --> 00:00:27,510 Well, in a pattern-matching operator, 11 00:00:27,510 --> 00:00:30,210 you perform an operation on a variable. 12 00:00:30,210 --> 00:00:32,010 If the variable is $1, 13 00:00:32,010 --> 00:00:34,080 which is the first positional parameter 14 00:00:34,080 --> 00:00:35,970 or the first argument that was provided 15 00:00:35,970 --> 00:00:37,440 while running the script, 16 00:00:37,440 --> 00:00:41,430 you can put the $1 between curly braces, 17 00:00:41,430 --> 00:00:44,256 and do ${1#}. 18 00:00:44,256 --> 00:00:46,830 That's not really a pattern-matching operator, 19 00:00:46,830 --> 00:00:49,680 but it prints the length of the string. 20 00:00:49,680 --> 00:00:51,033 And that can be useful. 21 00:00:51,930 --> 00:00:56,550 Now if you would use ${1#string}, 22 00:00:56,550 --> 00:00:58,140 then you are going to search for "string" 23 00:00:58,140 --> 00:01:00,180 and you'll remove the shortest match of the string 24 00:01:00,180 --> 00:01:02,610 from the front end of $1. 25 00:01:02,610 --> 00:01:03,960 There's also double-hash, 26 00:01:03,960 --> 00:01:06,810 and that will remove the longest match of the string, 27 00:01:06,810 --> 00:01:08,163 also from the front end. 28 00:01:09,720 --> 00:01:12,060 Then we have %string, 29 00:01:12,060 --> 00:01:14,550 which removes the shortest match of the string, 30 00:01:14,550 --> 00:01:16,020 and %%string, 31 00:01:16,020 --> 00:01:17,970 which removes the longest match of the string 32 00:01:17,970 --> 00:01:19,183 from the back end of $1. 33 00:01:20,880 --> 00:01:22,410 Let's have a look at some examples 34 00:01:22,410 --> 00:01:26,253 in patterns.sh, which is in the course Git repository. 35 00:01:31,260 --> 00:01:33,450 Okay, let's have a look at patterns.sh, 36 00:01:33,450 --> 00:01:36,270 which is a simple example script 37 00:01:36,270 --> 00:01:38,940 which is demonstrating what this is all about. 38 00:01:38,940 --> 00:01:40,470 So in this example script, 39 00:01:40,470 --> 00:01:43,590 we are going to provide a string as argument 40 00:01:43,590 --> 00:01:44,970 while running the script, 41 00:01:44,970 --> 00:01:47,940 like /usr/bin/blah, 42 00:01:47,940 --> 00:01:50,130 but you can use anything you want. 43 00:01:50,130 --> 00:01:51,060 This script is really 44 00:01:51,060 --> 00:01:52,230 a script that is looking for filenames, 45 00:01:52,230 --> 00:01:55,110 so it should look like a filename, 46 00:01:55,110 --> 00:01:57,540 that's the only thing that matters. 47 00:01:57,540 --> 00:01:58,860 Now, what are we going to do? 48 00:01:58,860 --> 00:02:01,830 Well, first we set the variable "filename" 49 00:02:01,830 --> 00:02:03,793 and filename is set to $1, 50 00:02:04,920 --> 00:02:07,590 and then we have double-hash */, 51 00:02:08,640 --> 00:02:11,790 So we are looking for */, 52 00:02:11,790 --> 00:02:14,313 which is a / with anything in front of it. 53 00:02:15,720 --> 00:02:19,590 Then we are looking for the longest match of this pattern. 54 00:02:19,590 --> 00:02:20,880 What is the longest match? 55 00:02:20,880 --> 00:02:24,030 Well, if we look from left to right in the string, 56 00:02:24,030 --> 00:02:26,460 now we are really searching for the last slash, 57 00:02:26,460 --> 00:02:29,430 and we remove it with all that is in front of it, 58 00:02:29,430 --> 00:02:31,740 so that the filename is remaining. 59 00:02:31,740 --> 00:02:36,740 And then we use echo filename is '${1 hash-hash */}' 60 00:02:37,680 --> 00:02:39,450 between single quotes. 61 00:02:39,450 --> 00:02:40,530 The single quotes make 62 00:02:40,530 --> 00:02:43,050 that we escape the pattern-matching operator, 63 00:02:43,050 --> 00:02:46,140 and we just print what is going to happen. 64 00:02:46,140 --> 00:02:51,120 That's easy for understanding what is going to happen. 65 00:02:51,120 --> 00:02:54,150 And in the next line, the name of the file is $filename. 66 00:02:54,150 --> 00:02:55,950 That is printing the "filename" variable 67 00:02:55,950 --> 00:02:59,460 that was set according to the pattern-matching operator. 68 00:02:59,460 --> 00:03:01,830 We do something similar for the directory name, 69 00:03:01,830 --> 00:03:06,390 but this time the pattern-matching operator is %/*. 70 00:03:06,390 --> 00:03:07,470 What does that mean? 71 00:03:07,470 --> 00:03:09,180 That means that from right to left 72 00:03:09,180 --> 00:03:14,100 we are searching for the pattern / followed by anything. 73 00:03:14,100 --> 00:03:18,030 It's a single %, so that will be shortest match. 74 00:03:18,030 --> 00:03:21,540 And the shortest match in this example would be /blah. 75 00:03:21,540 --> 00:03:25,140 So the remaining parts is the directory name, /usr/bin, 76 00:03:25,140 --> 00:03:27,480 and that is what's going to be printed. 77 00:03:27,480 --> 00:03:30,433 Let's run it so that we can see what's going to happen. 78 00:03:30,433 --> 00:03:33,433 (keyboard clacking) 79 00:03:34,590 --> 00:03:36,540 So in the script it is important 80 00:03:36,540 --> 00:03:40,473 that we provide an argument, /usr/bin/whatever. 81 00:03:41,880 --> 00:03:43,950 Really, it's not really important 82 00:03:43,950 --> 00:03:46,170 if it's an existing file or anything, 83 00:03:46,170 --> 00:03:48,450 it's just about what the pattern-matching operator 84 00:03:48,450 --> 00:03:49,470 is going to do. 85 00:03:49,470 --> 00:03:50,760 And what do we see? 86 00:03:50,760 --> 00:03:52,890 We see that it keeps the filename "whatever" 87 00:03:52,890 --> 00:03:56,820 and the directory name, which is set to /usr/bin. 88 00:03:56,820 --> 00:03:58,830 Now we are going to do something interesting, 89 00:03:58,830 --> 00:04:01,650 and we apply a couple of modifications. 90 00:04:01,650 --> 00:04:04,830 So for filename I am going to make that 91 00:04:04,830 --> 00:04:08,730 no longer hash-hash, but single-hash */. 92 00:04:10,620 --> 00:04:14,043 And for directory name, I make that double-percent. 93 00:04:16,440 --> 00:04:20,460 So we will be going in the opposite direction here, 94 00:04:20,460 --> 00:04:23,400 and then we are going to check what is going to happen. 95 00:04:23,400 --> 00:04:24,510 I would like to invite you 96 00:04:24,510 --> 00:04:26,700 to try to understand what is going to happen 97 00:04:26,700 --> 00:04:27,783 before running it. 98 00:04:28,740 --> 00:04:31,980 And once you have an idea, then you run it. 99 00:04:31,980 --> 00:04:35,700 To give you a hint, single-hash is shortest match. 100 00:04:35,700 --> 00:04:40,700 And to give you another hint, * is zero or more characters. 101 00:04:40,710 --> 00:04:42,480 So we are looking for the shortest match 102 00:04:42,480 --> 00:04:46,653 of a / with zero or more characters in front of it. 103 00:04:47,820 --> 00:04:48,813 Let's check it out. 104 00:04:52,590 --> 00:04:57,420 And there you can see what the single-hash */ is doing. 105 00:04:57,420 --> 00:05:00,000 It's just removing the slash in the beginning. 106 00:05:00,000 --> 00:05:02,940 So the remaining part is usr/bin/whatever. 107 00:05:02,940 --> 00:05:04,650 And for the directory name, 108 00:05:04,650 --> 00:05:05,700 well, the directory name 109 00:05:05,700 --> 00:05:08,340 is looking for the longest match 110 00:05:08,340 --> 00:05:11,280 of the pattern / followed by anything, 111 00:05:11,280 --> 00:05:13,860 and that happens to be the entire pattern. 112 00:05:13,860 --> 00:05:17,130 So the name of the directory is nothing at all. 113 00:05:17,130 --> 00:05:20,250 And that's how you can use pattern-matching operators. 114 00:05:20,250 --> 00:05:23,370 Pattern-matching operators are clean and they are fast. 115 00:05:23,370 --> 00:05:25,590 They are best internal solution, 116 00:05:25,590 --> 00:05:28,260 so you don't require anything to be loaded, 117 00:05:28,260 --> 00:05:30,570 and that is why you see pattern-matching operators 118 00:05:30,570 --> 00:05:31,983 quite often in scripts.