Files
hpr-knowledge-base/hpr_transcripts/hpr4113.txt
Lee Hanken 7c8efd2228 Initial commit: HPR Knowledge Base MCP Server
- MCP server with stdio transport for local use
- Search episodes, transcripts, hosts, and series
- 4,511 episodes with metadata and transcripts
- Data loader with in-memory JSON storage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-26 10:54:13 +00:00

250 lines
32 KiB
Plaintext

Episode: 4113
Title: HPR4113: Today I Learnt, sed hold/pattern space use.
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr4113/hpr4113.mp3
Transcribed: 2025-10-25 19:46:54
---
This is Hacker Public Radio episode 4,113 for Wednesday the 8th of May 2024.
Today's show is entitled, Today I Learned, Said Hold and Pattern Space Use.
It is hosted by some guy on the internet, and is about 35 minutes long, it carries a clean flag.
The summary is, Scoti talks about using said hold and patterned spaces.
You are listening to a show from the Reserve Q.
We are airing it now because we had free slots that were not filled.
This is a community project that needs listeners to contribute shows in order to survive.
Please consider recording a show for Hacker Public Radio.
The show notes are going to be pretty simple, it is just going to be a bash script down in there.
This bash script is going to be kind of unique because what it is doing is basically creating some things for you.
I wanted to make my older scripts more portable.
Basically what I am doing is cleaning out my bash RC.
There are a lot of things that I use regularly in my bash RC, but mostly on my desktop computer, not on like my laptop and stuff like that.
Whenever I drag my bash RC over to my laptop, my laptop for one uses wailing where my desktop is using Xorg.
There are commands that edit the clipboard or manipulate the clipboard on Xorg that don't work on the wailing system.
There are small differences like that that don't make it as portable as well as, again, some of the other functions like I create shows in depth on my desktop system because that is from a microphone and everything is on my laptop not so much.
But I still want the functionality, it just doesn't all have to be within the bash RC.
So by exporting some of those additional functionalities into their own individual scripts and they were calling those scripts from a local bin and making sure that the scripts are portable.
It still gives me the same flexibility and I get to make a show out of it all.
So this is what part of the result of that I wrote a script and made it to where I did what this script is going to do is first search where you keep your binaries.
So I'm going to I'm on in a Ubuntu based distribution.
So it's in a usr bin universal system resources binary directory.
We're going to reach down in there, perform an LS to give us the list of all of the system resources in there and then make some things out of that.
And it's pretty pretty fun.
So let's get right into it.
So as we move into the variable section of the script here, you're going to see the first variable again, usr slash bin.
And there are the resources that I'm using in the script right there, which are all cat show mod and a few other things.
So you can see everything that I'm using.
And this script has also had everything applied to it.
I had to because I was writing the script, I had to manually apply everything at first and then, you know, the script was designed to create the tool to fix the script.
So there you go.
So we got the we got our little echo debug statements that are sprinkled in here.
So anytime you see like an echo step script, a step line, that's just your little debug lines right there.
All right. So the first thing that we do here that I want to let you know that we're doing, we're using mk temp.
Now part, I use mk temp every day.
Like when I load up my my bash rc, what I should do instead of just having it as a function, I should just break it out of the function and have the raw f statement in there.
Just so that I can always have a temporary directory of my own that I want to use because I call it every single day.
I call the function soon as I load up.
First thing I do is call that function.
So I might as well just break it out.
But with mk temp is doing here in that very first function, the mk t function that's up there is we're going down into the slash tmp directory.
And we're creating our own temporary directory within it and we're using mk temp to do it.
mk temp is a lot like mkder make directory except is designed for making temporary directories.
Now you can sort of see my standard directory nomenclature.
I use the date capital F, which gives you, what is that?
Is that like the universal date thing where it's like the four digit year, two digit month, two digit day separated by hyphens?
That's typically how I name a lot of my generic directories and then inside of those those directories go the files.
And the files are named very similarly as well, except the date at the beginning of the file does not have hyphens in it.
So the directory will have hyphens, but the file will not, you know, for the more generic stuff.
And this just lets me know when I created that file or when I created that directory or whatever it is, you know, because it's a part of the name.
And as well as whenever you need to clean things out, so like when I'm doing my tar balls, well, I'm getting too much into the weeds here, but I'll wrap it up pretty quickly.
When I'm creating the tar balls for things that I want to back up by giving it this nomenclature, I can easily see that, okay, there's a bunch of stuff that was created back in January of 2023.
I no longer need those, so I can just easily clean up everything from January to say June and keep everything from July on forward.
That kind of thing. So it's very easy to get through things that with a nomenclature like this.
So we create our own temporary directory and all those x's afterward, the mk temp command explains to you that each of those x's become a random character.
So that way you never create the same directory twice. And the f statement is designed to check if you already have one of these, you know, my style of directing nomenclatures made.
So that way you don't continuously keep creating new directories every single time you run the command or whatever.
It'll check first to see if one's there and if so, then it'll place whatever needs to be placed inside of that directory.
So there you go. And again, it's in a function here, which it doesn't need to be in a function.
I could actually just break it out and use the raw f statement and it'll do what it's got to do.
But I have a habit of writing functions now. Shout out to black colonel, we're brothers and don't listen to him if he denies otherwise.
You see a couple of director, you see a couple of variables right down here for the documents that's going to be created.
So again, my nomenclature that I use year, month date variable name, I mean a file name.
So we're creating three files. We're creating a text file, a dot vim file and a said file.
And we're going to be using said primarily for most of it.
I'll tell you what they're going to do. First of all, I'll tell you how you're supposed to use these how I intended for them to be used.
And then you just do whatever you want to do afterwards. Right. So I intended for the variables dot text file to be read in using something like them.
So you know how you when you're in them, you can read a document into whatever document you're working with.
Yeah, that's basically what I deal with that one. So very simple. You just read it in and what that'll do is a list.
It's going to give you a list of everything in your usr slash bin, but in that variable style that I have up at the top of the script up there.
So right up there where I have the binary directory followed by each of the different things that are being used to manage the script, you know,
all said, etc, etc. That kind of actually I don't even think all because being used in here. I think it was being used, but then I took it out because I figured out what I would needed to do was said to eliminate the use of all the other stuff.
But I'm not going to take it out now just in case I was wrong and then I ended up breaking the script before upload. So there you go.
But yeah, you just you just get a list of everything that's in your way where your system keeps the binaries and it it automatically creates them into a bash style variable list.
So you could just read that file directly into your bash script and then begin creating links based on the ones that you use.
Now what I'll do later on when I get to the ended file is teach you how to eliminate the ones that you're not going to use because obviously like on my system, I have like over a thousand different things in there.
Obviously in a script, you know, like in this script right here, I'm not even calling even 10 different commands. So why would I need all 1000 right?
I know that's what you're asking, but don't worry. I'll show you how we're going to take care of that later on.
The second thing that we're doing is I create a bash dot them file, which is like a custom session. So you can source that if you're writing a bash script, you can source that bash dot them file.
And that'll give you the ability to do things like abbreviations that automatically turn the commands that you type like a LS or cat or whatever into the variable style that I use here.
You'll see like with all of my variables and even my commands that I'm calling which are made into variables because they're being linked from the actual commands up above.
So like date, for instance, I'm looking at date, it has the brackets around it, the curly brackets along with the dollar sign. So each time I type the word date, it automatically, you know, has them does when you have an abbreviation setup, it'll rather than have the regular date, it'll change it into the, you know, date with the brackets around it, as well as all the other things that are listed.
So hopefully that made sense for to you. And for the last file there, that said script dot said file. Basically, we're just going to create a set script and what the set script will do is it's intended to be used like this from my older scripts.
When I'm inside the script and I realize, hmm, the script has not been converted over yet. I'll hop inside that script. I will create a, what do you call it, a visual selection, you know, use a capital V and drag down to to the address range or whatever, whatever range I want to use, I'll highlight that range using capital V. And then I will do a, you do command.
And then you call the script on that range. So you do command space or no, you don't even need to space. You do do a question mark, not question mark, what is it called, exclamation mark, script name or command name, whatever command you're running on that range, you could just do it like that. So if you're running sort, you could just run, you know, use the sort command with exclamation mark sort.
But since we're calling a script, which is the script that will be made using this script, you know, it'll, it'll allow that said script to, again, it said, so we're using a series of basic said substitution commands that are based off of my, because I ran the script on my computer is based off of where my system keeps us binaries.
So it's going to be able to take all of the regular binary names in your script and convert them over into the, you know, the, the, the variable style, where, where it links to the variables that you will then have at the top defined.
So because that is how I do things, that is how I designed it to work, or that is how I intend for it to work, you know, so let's go down here into the script enough for my rambling and let's talk about it.
So we got a here document. This here document will, what are we doing? Okay, so we're in variables to text document. First thing we're doing in the here document is we're setting up the binary directory for your system.
And again, for my system is us are bin. So for you, you just going to change that to wherever your system keeps the binaries, we end the here document and then we hop right down to the good stuff.
The body of the document, which is created by said, now we're using said with its pattern space and hold space shout out the Dave Morris for his learn said shows that he's done.
He does a great job and he explains it much better than how I've read it in the books that I have. I have multiple said books that that use it, but in some of the books that I have, they use some examples with a language called trough, I think it's called.
And I don't even know, I don't have a, I didn't even bother to look it up. So what trough is and what it's used for, I just know it looked weird and it was a terrible example to use when trying to teach someone something like pattern spaces and hold spaces and just rejects through said in general can get pretty complex.
So the last thing you want to do is teach it with another language, if you will, you know what I mean, just kind of, or if you're going to use a language, use something simple like for instance, we're dealing with it in bash or just, you know, just get some generic text and use it with it, something.
So it kind of got a little, it was difficult and I think it was unnecessarily difficult to learn that way, but they've made it very clear and much, much simpler, but at the time when I'm listening, I'm not behind the computer at the time.
So I have to try and remember as much as I can and get back to the computer and then try to listen, but I got a three year old, you know, screaming and jumping all over the place. So get past all of that to trying to learn said, which, as you can imagine, it's kind of difficult.
But I figured it out and I know it's not perfect. I can tighten it down a little bit more. However, I'm not going to because I might break it and it'll delay the show. So.
So here you go. It works right now and then you're going to, you're going to use it and you're possibly going to enjoy it. So what we're doing. I'll talk you through it the best that I know. So we're calling LS LS with the one, which you don't even need to one.
But I put it there just to be safe where it's just going to list everything that's in the directory and the directory where aim that for me is the USR bin, which I should have used the variable for that because that that never mind. I'm again, I'm not going to it will delay the show. So I'm not messing with it.
But that may be an area where you need to change it. So that way I could put that same variable that had up there right down there. Actually, but again, I'm not going to mess with it because I break the thing and I don't feel like messing with that.
But we're calling LS to look at that directory list everything from that directory pipe it in the said once you pipe it in the said we're going to use the end flag or the end option with said to suppress the output from said.
And the reason we want to suppress the output from said is because there are specific things we want to print out any order that we want it to be printed out. If you don't do that, what's going to happen is everything will be printed out twice like you'll have the crap.
You don't want and the crap you do want being printed out. So we use in to suppress said natural wanting to print stuff out to standard out. Now we're going to call hold immediately.
So everything we fed in the said, which is the listing of our USR bin, hold the copy of that. So like taking a sheet of paper with all of that, you know, all of the binaries printed onto it.
Hold this for me for a second Dave. So just hand it over Dave. He's going to hold it. Now I also have a copy of that that I'm going to manipulate really quickly. So Dave's got a copy and I got a copy. Now I'm going to run it down into the next step, which is a said substitution here, which basically says anything that's not a number or a letter, get rid of it.
So any hyphens and periods and crap, get rid of it. Then I'm going to say, hey, Dave, let me get that copy that you have, because mine has already been manipulated. Right. So each of the, each of the binaries that I have listed have had all of their special, I'll just call them special characters right there. The non alphabetical numerical characters stripped out. So periods and dash is gone on my copy. Dave copy is still pristine. The original design.
I know the binaries with the periods and dash is still on it. So I got his copy and my copy here. That's what the G is doing. Now right next, the next line here, you're going to see the said substitution, which gets rid of new lines.
So what's happening is all of my copy or on one line and all of Dave copy is on another line or just think of it as a line, because it'll, it'll make much more sense here when I, because I know you're probably thinking there are several lines within each page. Yes, I know, but I'm trying to oversimplify it so we can get through it in a reasonable time.
So what we're doing is we're getting rid of the new line. So now each document here, Dave's document and my document are now on the exact same line. So they're all lined up now on the exact same line. So you have the pristine version that Dave held for me and my version that has been manipulated to eliminate all of the dashes and periods and stuff, all on the same line.
So then we run the next substitution down there, which gives structure to everything that we have. So basically it's saying, take the first document, hold it here and then add the variable structure of equal dollar sign, you know, curly bracket,
bender, you know, the thing that I put up there at the top that has the explanation for where the system binaries are held or definite, you know, is defining with the system binaries are held. Yeah, go ahead and put that structure here.
So what we're going to have is my copy, which is the modified version without periods and stuff using the bash variable referencing syntax,
leading to the version that Dave held for me, which is the actual binary names with all the periods and dashes and stuff included into it.
Now print that out because that's the one. That's what we want. Once it's structured the way we want it and it will print that out and by the moment of being now you have a complete variable list for bash of all of your system variables.
I mean, not of your system variable, your system binaries, but you know, in the variable style for your bash grip.
Whew, goodness me. That was a lot. Now where we're still.
Oh, yeah, I trim up and in the boom to for some reason, there's a binary or something in there that is simply an opening square bracket.
So I just trim that out. That's what that that second said statement is right there. Just trimming that out of there.
Then we get a little debugging debugging echo followed by the bash vim file.
So now we're creating the bash vim file. We start off with a here document, which spells out here.
This is one of the ways that I do in my custom bash and not bad in my custom vim sessions.
This is a way that you can use abbreviations in a vim session.
So it's going to be difficult for me to explain this, but if you'll see it, you'll probably make more sense of it than I can explain.
But there's a couple of abbreviations that help you quickly create a case statement.
So it's like boilerplate. That's all it is when you want to create a very quick case statement and just get kind of the boilerplate out the way.
I included that in there because again, this is this is how I use it.
And I figure for those of you learning, you could possibly learn some more about creating your own custom vim sessions as well as how to do your own boilerplating with vim for bash.
Hopefully that made sense. But there you go.
So you can see I have my case statement right there, which is a very simple one and a here document in there.
So when I want to call here documents, I got a very simple one right there, same thing for functions, F statements and aliases.
So when I'm working in my bash alias, I can quickly create aliases.
This is another thing for said that next one down in there.
And I have more that I can include in there, but I just I just wanted to get the thing working first.
And then maybe I would go back and add more to it, which I forgot to do.
Now that I got it working, I was like, like screw it, just get it out the door. Otherwise, I'm never going to get it out before the new years is over with.
They sure won't be posted until 2024, but you know, we're on December 31st right now.
So now let's go ahead and talk about the said state, the said usage that will create this bash.vm file.
And I'm going to go kind of quickly on this one.
So not as deep an explanation here, but you know, maybe we'll see.
So we're using LS again to go ahead and get the list from us r slash band.
We're going to pipe that in the said.
I'm going to say here, Dave, hold the pristine copy of that for me once more.
And I'll take my copy, run it through the same thing, which you know, takes out all the special characters.
Then I'm going to ask Dave for his copy back so that I can then take away the new lines, putting them all on the same line again and restructuring them to create the proper output that we want.
And in this case, it is creating a vm session file that can be sourced from them to your whatever bash script you're writing.
So that way it will automatically change your usage of the things listed in your universal system resources binary folder or wherever your system keeps the resources.
It will automatically change those into the variable form that I discussed above.
There you go.
Now right below that is going to be another here document.
And that is going to create the rest of the substitution list down there because I wanted to remember everything that was done in the first thing that I explained up above the file that you would source in or not that you a source and that you would read in.
Well, instead of reading that into here, I just kind of recreated it with another said thing.
So basically we're recreating that inside of the bash dot them everything that we did in the was a call that that first file the variables dot txt were also creating that in the bash dot them in a way that's useful though for the bash dot them.
So when you if you're on a Ubuntu based distribution that will be cleaned up pretty simple and easy for you.
And if you want to Dave if you're or whoever if you're listening and you are adding the show to the queue and you want to clean up that section there where I didn't put the binary.
I mean, I didn't put the variable for LS where I use the LS dash one and I have it written out as universal system resources been.
That could just be a variable there instead of the you don't think as you can see just talking about said just kind of gives you a little is different.
But in here we're going to move on down to where to go down to the said script this time now let's go ahead and get this ad script out the way.
We add our shabang in at the top of our said script and we make it to where this shared this ad script can be ran independently that way when we call it as a command from within them.
And again, once you once you use show mod to make it executable because you're going to have to do that for it to run.
If you don't make it executable, it's just a it's just a text file and I made sure that by while talk to you when we I'll let you know when we get down there to that part.
But I had to shabang in with the space with that that first here document.
Now we get into said using the same structure as above at less to the universal system resources binary pipe that and said here Dave hold this copy is pristine.
I'll go ahead manipulate my copy butcher it to pieces good heavens now David let me hold your copy again.
And then we're going to go ahead and get rid of the new lines put them on the same line restructure it into a usable format.
And then I'll put that into a file in that file will become a said script which contains a ton of substitutions that can be used from them or wherever really depending on how you want to use it.
I recommend using it from them because you can use addressing a lot easier that way you know you're actually looking at the address range the
depending on whether you want to call it address or range I guess if you're specifying it as a number will be an address but because we're visually highlighting it.
It's a range but you can you can select a range aim that script at it and then you know fired off change everything that you want change quick and simple easy and you know less to backfire.
And because you're doing it within them if you hit a section that you know whoopsie Daisy didn't mean do that you can hit just hit undo good to go.
And again there's a second set script is right underneath that because on the Ubuntu based distributions it's got that open bracket thing in there that gets called so we go ahead and strip that out there.
Now at the bottom you see two fine commands down there being used those fine commands are basically saying okay everything inside of this temporary directory that we created everything in there just give it some more secure permissions.
So for the directories themselves you know it should just be for the owner of the directory only to have the only necessary permissions same thing for files like files don't need executable except for that said script if you want to run it.
You know once you go in there take a look at it of course make sure everything is to your liking then obviously you just you know they could add make it executable from there.
So you can just change it to 700 for the set script as well the same way that I'm using show my there and by the boom by the bank you're good to go.
So very thirsty now and I hope that that made some kind of sense for how this script works.
Yeah right now what I did say we're going to go through an example here so let me go ahead and send some in them now.
First thing first let me save my work then let's go ahead and use e to open up a blank file called a delete was just going to be a buffer.
I'm not even going to say so delete there you go.
So we're opening up a buffer called delete and what we're going to do is we're going to all crap.
I did not um okay so let me hop to a terminal real quick as I didn't run the command I'm going to am I inside of a socket.
Let's see if I'm in a socket here it appears I am in the socket apps so let's bet no no I'm in a I'm in job be good.
Okay so let's do a doors here to see if I have my stack set up I am so we're going to do a PD plus 15 to take us back to our temporary directory where we can now run the grab.
Then script which will create everything that we just said.
So now we're going to L a which will show me everything that we just created.
Yep there we go I got the bash dot them that said script outside and the variables dot tasty.
So what we're going to do now is I want to switch right back to them here.
And I'm actually in GVAM but you know still then let me just do command R to read into this file.
And then we are going to link to temp to do the name do the name again and read in that variables text.
So we're going to read in the variables text.
So that's one way of getting all of the variables into your file.
Now I'm going to undo that and what I'm going to do this time is I'm going to source.
So now let's go ahead and do command s o space and now let's link to file which will be.
It will be that that bash dot VAM file this time.
So we're doing s o link to that bash dot VAM file so we're sourcing that file.
Now if we want to add all of those variables in our new bash script.
What we do is we hit I to enter insert mode then we will go ahead and type in V a R S semicolon.
And then we can just hit escape and bottom bottom bottom thing is just pre populated the document with all of the things that we that we wanted there.
Okay now for the ones that we do want what we could do is very simple what I do is I hop to the top of the stack there right.
So at the top of the variable list that we just created I do a capital V then I hold down shift and hit the curly break bracket thing to take me all the way down to the bottom of the stack there.
So now I have my what I call it earlier not address the thing that I said earlier other than range I have my range.
So now we do a command within my range what I want to do is run a quick little said style substitution within that range.
So I can do let's say we're going to look for echo so we want to type in.
I got my little S with the three forward slashes and then I use the arrow keys to move back within the first you know the thing that will be substituted.
So we type an echo right there so about a boom it found echo but what we want to do is make sure that is the proper echo let's just pretend that they are multiple echoes in there whatever.
So there's an echo then there's an echo something or other or or let's find another file that actually has GPG there you go so there's GPG in there.
And as you can see with GPG there is GPG agent GPG cough but we don't want all of that right now we're just calling GPG not all the other ones.
So what we do is we go ahead and put the first thing we do is we put the care at the front of GPG and we put the equal sign at the back of GPG.
So that it specifies the one that we actually want now what we're going to be substituting it with in the substitution section.
We're going to add one two three four spaces and then do an ampersand and what the ampersand is the rejects that were substituting is being recalled.
So basically we're indenting the line that's all we're doing and then we hit enter.
But a boom that lines indented now what I do is now that I've indented that one that I wanted.
I do a G V which reselects my range again command then I hit up which pulls the same substitution that I just had.
I use the arrow key to go back and be where I had GPG and I just erase that and put in say echo.
But a boom so now I just hit enter now that I have echo now echo is indented and I do that for all of the ones that I'm actually calling within the script right.
So now that the script I have everything that I want indented that I'm going to keep now for the stuff that I don't want to keep you know what I do.
I once again call that range so G V I call that range command then we do a G forward slash.
Let me write this out we got to specify the front of the line there.
So we do the carrot and then we do the open square bracket.
Alright I had to cut real quick and come back in.
I already wrote it out once you specify your range you start off with the G forward slash carrot open square carrot four spaces
closed square four slash D and what that is that's giving you the global search with the delete command and you're going to delete every line within the range that is not indented with four spaces.
So you press enter on that and by the boom by the bank everyone that you indented will be left behind but the ones you did not are gone.
You can do the exact same thing without indenting so for instance if you just wanted to add like a hash at the front of the line.
And then you could you know again with that same specification there every line it does not have a hash remove.
But I use indenting because indentings a lot easier to correct than the hash you could do the control V selection method to specify a special range in order to get rid of it.
But I'm not going to do all that with you know but we're not doing a whole ton of them here.
We're just showing you how that is supposed to be ran and there you go.
Oh do I want to save and if I know that's just a buffer.
I don't want to save that to a file.
So let me do a control L real quick to clearly highlighting shout out today more important that out and yeah that's the end of the script.
Alright I hope it all works and if you want just remember that one section down there where the
with the LS is being ran the LS option one that's being ran you can swap that out for a variable.
Just remember that and you'll be fine.
Especially if you're on the non Ubuntu based distribution.
Alright that's all I got time for.
I'm out take it easy.
You have been listening to Hacker Public Radio at Hacker Public Radio does work.
Today's show was contributed by a HBR listener like yourself.
If you ever thought of recording podcasts you click on our contribute link to find out how easy it really is.
Hosting for HBR has been kindly provided by an honesthost.com, the internet archive and our things.net.
On this otherwise stated today's show is released under Creative Commons
Attribution 4.0 International License.