{"id":2354,"date":"2015-10-01T18:17:18","date_gmt":"2015-10-01T17:17:18","guid":{"rendered":"https:\/\/stevepedwards.today\/DebianAdmin\/?p=2354"},"modified":"2023-11-09T02:42:50","modified_gmt":"2023-11-09T02:42:50","slug":"sed-basics-using-o_reilly-pdf-example-and-unexpected-mind-bending-parsing-behaviour","status":"publish","type":"post","link":"https:\/\/stevepedwards.today\/DebianAdmin\/sed-basics-using-o_reilly-pdf-example-and-unexpected-mind-bending-parsing-behaviour\/","title":{"rendered":"SED Basics using O_Reilly.pdf example, and Unexpected Mind-Bending Parsing Behaviour"},"content":{"rendered":"<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_2354\" class=\"pvc_stats all  \" data-element-id=\"2354\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/stevepedwards.today\/DebianAdmin\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p>The O_Reilly.pdf pdf of this 1990 book refers to POSIX standard changes in SED etc. so may account for different behaviour by my Mint version of grep, sed and awk etc. from their original examples, as I think happened below.<\/p>\n<p>As an introduction to the ideas of iteration and recursion using SED:<\/p>\n<p><span style=\"color: #222222;\"><i><span style=\"font-family: arial, sans-serif;\"><span style=\"font-size: medium;\">In simple terms, an <\/span><\/span><\/i><\/span><i><span style=\"color: #222222;\"><span style=\"font-family: arial, sans-serif;\"><span style=\"font-size: medium;\"><b>iterative <\/b><\/span><\/span><\/span><span style=\"color: #222222;\"><span style=\"font-family: arial, sans-serif;\"><span style=\"font-size: medium;\">function is one that loops to repeat some part of the code, and a <\/span><\/span><\/span><span style=\"color: #222222;\"><span style=\"font-family: arial, sans-serif;\"><span style=\"font-size: medium;\"><b>recursive <\/b><\/span><\/span><\/span><span style=\"color: #222222;\"><span style=\"font-family: arial, sans-serif;\"><span style=\"font-size: medium;\">function is one that calls itself again to repeat the code.<\/span><\/span><\/span><\/i><\/p>\n<p>Experiment with some examples of SED, to try to understand how it works line by line, as a script proceeds, with any changed values in the first line becoming possible targets for change by subsequent script line commands as it's not obvious at first how it works, or to visualise, (especially if you are a crap programmer like me!) like much with grep, sed and awk - depending on what regular expression methods and metacharacters are used.<\/p>\n<p>Here's the pig, cow, horse example in the book,\u00a0which I think contains omissions re the global function - states:<\/p>\n<p><i>Let's look at an example that uses the substitute command. Suppose someone quickly wrote the<\/i><\/p>\n<p><i>following script to change \"pig\" to \"cow\" and \"cow\" to \"horse\":<\/i><\/p>\n<p><i>s\/pig\/cow\/<\/i><\/p>\n<p><i>s\/cow\/horse\/<\/i><\/p>\n<p><i>What do you think happened? Try it on a sample file. We'll discuss what happened later, after we look at how sed works.<\/i><\/p>\n<p>At this point, I guessed the script would change all pig words to cow words, then all cows to horses, (which I assume is what most people would?), so that only the word horse would exist in place of previous pigs and cows. It's not clear what the fictitious scriptwriter actually intended though, from the text.<\/p>\n<p>Did he want to substitute\u00a0all \"pig\"\u00a0<i>and<\/i>\u00a0\"cow\" words with \"horse\" in the first place or just some? Can SED do that on one line or does it need two lines?<\/p>\n<p>So, create the script as above:<\/p>\n<p><span style=\"color: #0000ff;\">cat scriptest.txt<\/span><\/p>\n<p><span style=\"color: #cc0000;\"><i>s\/pig\/cow\/<\/i><\/span><\/p>\n<p><span style=\"color: #cc0000;\"><i>s\/cow\/horse\/<\/i><\/span><\/p>\n<p>and a suitable file to apply it to:<\/p>\n<p><span style=\"color: #0000ff;\">cat pigcowhorse.txt<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse pig<\/span><\/p>\n<p><span style=\"color: #ffffff;\">It would seem that each word pig would first change to cow in the process, then all the new cow values would change to horse if you think the first line acts on the whole file before the 2<sup>nd<\/sup> line acts, to penultimately change each pig to cow:<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow cow horse cow<\/span><\/p>\n<p><span style=\"color: #ffffff;\">so that ultimately, cows become horses by the incredible way sed may swiftly alter their genetics:<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse horse horse<\/span><\/p>\n<p><span style=\"color: #ffffff;\">as the rushed scriptwriter possibly overlooked, from what he desired? <\/span><\/p>\n<p><span style=\"color: #ffffff;\">If you run this script, it does neither that, nor what the example intends to show, I believe, as some cows don't become horses, and a final pig remains un-mutated:<\/span><\/p>\n<p><span style=\"color: #ffffff;\">stevee@Mint5630 ~\/Documents\/SEDAWK $ <span style=\"color: #0000ff;\">sed -f scriptest.txt pigcowhorse.txt<\/span> <\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse cow horse pig<\/span><\/p>\n<p><span style=\"color: #ffffff;\">The authors intended the script to act as explained:<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><i>As a consequence, any sed command might change the contents of the pattern space for the next<\/i><\/span><\/p>\n<p><span style=\"color: #ffffff;\"><i>command. The contents of the pattern space are dynamic and do not always match the original input line. That was the problem with the sample script at the beginning of this chapter. The first command would change \"pig\" to \"cow\" as expected. However, when the second command changed \"cow\" to \"horse\" on the same line, it also changed the \"cow\" that had been a \"pig.\" So, where the input file contained pigs and cows, the output file has only horses!<\/i><\/span><\/p>\n<p><span style=\"color: #ffffff;\">To understand what happens, you need to go in steps, as sed does in the script:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">sed s\/pig\/cow\/ pigcowhorse.txt <span style=\"color: #ffffff;\">(&gt; cows.txt)<\/span><\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow cow horse pig<\/span><\/p>\n<p><span style=\"color: #ffffff;\">Now you see why the pig gets left. Sed only acts on the first occurrence on each line.<\/span><\/p>\n<p><span style=\"color: #ffffff;\">You can guess now what happens the next time round if only the FIRST occurrence of cow gets substituted by horse (s\/cow\/horse\/) and all else left alone, same as the result I got above: <\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse cow horse pig<\/span><\/p>\n<p><span style=\"color: #ffffff;\">What the authors forgot possibly due to different sed version behaviour since theirs in 1990 to give us all horses was the global command, g, so that all occurrences of the searched term get substituted on each line:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">cat scriptest.txt <\/span><\/p>\n<p><span style=\"color: #cc0000;\">s\/pig\/cow\/g<\/span><\/p>\n<p><span style=\"color: #cc0000;\">s\/cow\/horse\/g<\/span><\/p>\n<p><span style=\"color: #ffffff;\">so that ALL pigs become cows, then ALL cows become horses, which when run globally, you do indeed get all horses:<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #0000ff;\">sed -f scriptest.txt pigcowhorse.txt<\/span> <\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse horse horse<\/span><\/p>\n<p><span style=\"color: #ffffff;\">Again, you can run the single sed lines to see the global substitution effect of all occurrences of the searched word on each line. The first pass changes all pigs to cows, the second, all cows to horses:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">sed s\/pig\/cow\/g pigcowhorse.txt <span style=\"color: #ffffff;\">(&gt; cows2.txt)<\/span><\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow cow horse<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #cc0000;\">cow cow horse cow<\/span> <\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #0000ff;\">sed s\/cow\/horse\/g cows2.txt<\/span> <\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">horse horse horse horse<\/span><\/p>\n<p><span style=\"color: #ffffff;\">So this is what the authors were driving home they just left out the global command aspect unless their 1990 version worked differently:<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><i>As a consequence, any sed command might change the contents of the pattern space for the next<\/i><\/span><\/p>\n<p><span style=\"color: #ffffff;\"><i>command. The contents of the pattern space are dynamic and do not always match the original input line. That was the problem with the sample script at the beginning of this chapter. The first command would change \"pig\" to \"cow\" as expected. However, when the second command changed \"cow\" to \"horse\" on the same line, it also changed the \"cow\" that had been a \"pig.\" So, where the input file contained pigs and cows, the output file has only horses!<\/i><\/span><\/p>\n<p><span style=\"color: #ffffff;\">It seems what they were suggesting, that was desired by the scriptwriter, was to have been achieved by changing the script command order, but not globally either:<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><i>This mistake is simply a problem of the order of the commands in the script. Reversing the order of the commands - changing \"cow\" into \"horse\" before changing \"pig\" into \"cow\" - does the trick.<\/i><\/span><\/p>\n<p><span style=\"color: #ffffff;\"><i>s\/cow\/horse\/<\/i><\/span><\/p>\n<p><span style=\"color: #ffffff;\"><i>s\/pig\/cow\/<\/i><\/span><\/p>\n<p><span style=\"color: #ffffff;\">This time, if the script is edited as above, (no global option), and run on the original file you would get from:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">cat pigcowhorse.txt <\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse pig<\/span><\/p>\n<p><span style=\"color: #ffffff;\">to<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #0000ff;\">sed -f scriptest.txt pigcowhorse.txt<\/span> <\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow horse horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow horse horse pig<\/span><\/p>\n<p><span style=\"color: #ffffff;\">Again, an unchanged pig left over. <\/span><\/p>\n<p><span style=\"color: #ffffff;\">Compare that with adding the global g:<\/span><\/p>\n<p><span style=\"color: #ffffff;\">s\/cow\/horse\/g<\/span><\/p>\n<p><span style=\"color: #ffffff;\">s\/pig\/cow\/g<\/span><\/p>\n<p><span style=\"color: #ffffff;\">to get what I think they meant the scriptwriter meant for all along all <b>original<\/b> pigs ONLY get changed to cows, and all <b>original<\/b> cows ONLY get changed to horses!:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">cat pigcowhorse.txt <\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse pig<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #0000ff;\">sed -f scriptest.txt pigcowhorse.txt<\/span> <\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow horse horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">cow horse horse cow<\/span><\/p>\n<p><span style=\"color: #ffffff;\">Only working patiently through these types of examples will you discover errors like this, and think about what is going on, to get a feel for how easy it is to error in the initial thought process of how you think things may work, to how they turn out.<\/span><\/p>\n<p><span style=\"color: #ffffff;\">The next sed example is a handy one liner for removing blank lines, so I insert 4 in pigcowhorse.txt:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">cat pigcowhorse.txt<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">---<\/span><\/p>\n<p><span style=\"color: #ffffff;\">From grep, and knowing that the (^) denotes the first char of any\/every line as even blank lines by definition, have to have a null char of some sort to separate it from the next line, so therefore a last character ($) also, by definition, which would be a line feed (LF char) or similar.<\/span><\/p>\n<p><span style=\"color: #ffffff;\">You can find all empty lines in a file using these special characters together - the first and last chars with NOTHING between them = a blank line. <\/span><\/p>\n<p><span style=\"color: #ffffff;\">For the 4 blanks in pigcowhorse.txt you get a gap (which I numbered below) in the tty where grep finds only the 4 empty lines:<\/span><\/p>\n<p><span style=\"color: #ffffff;\">stevee@Mint5630 ~\/Documents\/SEDAWK $ <span style=\"color: #0000ff;\">grep ^$ pigcowhorse.txt<\/span> <\/span><\/p>\n<p><span style=\"color: #ffffff;\">1<\/span><\/p>\n<p><span style=\"color: #ffffff;\">2<\/span><\/p>\n<p><span style=\"color: #ffffff;\">3<\/span><\/p>\n<p><span style=\"color: #ffffff;\">4<\/span><\/p>\n<p><span style=\"color: #ffffff;\">stevee@Mint5630 ~\/Documents\/SEDAWK $<\/span><\/p>\n<p><span style=\"color: #ffffff;\">You can use this with sed combined with the d delete option to remove those lines from a file (note the WordPress editor adds extra lines also when pasted - but you realise there is no line space between these in the Terminal?):<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #0000ff;\">sed '\/^$\/d' pigcowhorse.txt<\/span> <\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">--- <\/span><\/p>\n<p><span style=\"color: #ffffff;\">Extending that regex, you can use grep, as cat, to view any file, using the . period, which denotes any single character; along with the asterisk * wildcard, which denotes none OR any number of any characters. <\/span><\/p>\n<p><span style=\"color: #ffffff;\">This means the first character of any line (which has to exist for there to be a line in the first place), can be followed by anything or nothing, and be displayed as a search result by grep, i.e. the whole file's contents!<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #0000ff;\">grep ^.* pigcowhorse.txt<\/span> <\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse<\/span><\/p>\n<p><span style=\"color: #cc0000;\">pig cow horse pig<\/span><\/p>\n<p><span style=\"color: #cc0000;\">---<\/span><\/p>\n<p><span style=\"color: #ffffff;\">These two one-liners are handy to check your understanding of four common special characters (^.*$) which can mean different things to the command line, depending on how they are bounded by each other. For example, if you list the attribs of Documents with the dir option d, you get a single line output from ls:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">ls -ld Documents\/<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #cc0000;\">drwxr-xr-x 4 stevee stevee 4096 Sep 30 10:36 Documents\/<\/span> <\/span><\/p>\n<p><span style=\"color: #ffffff;\">If you pipe that to grep to search for any single character in that line, you get the whole line as you may expect:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">ls -ld Documents\/ | grep .<\/span><\/p>\n<p><span style=\"color: #ffffff;\">d<span style=\"color: #cc0000;\">rwxr-xr-x 4 stevee stevee 4096 Sep 30 10:36 Documents\/<\/span><\/span><\/p>\n<p><span style=\"color: #ffffff;\">You may think that grep would still only read the content stream of it's input from ls -ld, if you added the wildcard; <\/span><\/p>\n<p><span style=\"color: #0000ff;\">ls -ld Documents\/ | grep .*<\/span><\/p>\n<p><span style=\"color: #ffffff;\">to show none or all characters after any single character (found by the period), but it doesn't do that by a LONG way it lists <b>all<\/b> the characters after any <b>single<\/b> character, found in the actual Documents directory - some 418 files, as if you used grep alone in the first place:<\/span><\/p>\n<p><span style=\"color: #0000ff;\">ls -ld Documents\/ | grep .* <span style=\"color: #ffffff;\">is equal<\/span> to grep .* <\/span><\/p>\n<p><span style=\"color: #ffffff;\">Why isn't it listing just the single line that defined the Documents line, which has a first character d (from drwx etc.), followed by none or any amount of any other characters i.e. the input stream alone, from ls -ld? <\/span><\/p>\n<p><span style=\"color: #ffffff;\">It seems the command line parses the . period after grep, and expands as a current directory node, which is also a . period, as seen by using:<\/span><\/p>\n<p><span style=\"color: #ffffff;\">stevee@AMDA8 ~ $ <span style=\"color: #0000ff;\">ls -al<\/span><\/span><\/p>\n<p><span style=\"color: #cc0000;\">total 140<\/span><\/p>\n<p><span style=\"color: #cc0000;\">drwxr-xr-x 24 stevee stevee 4096 Oct 1 16:51 .<\/span><\/p>\n<p><span style=\"color: #cc0000;\">drwxr-xr-x 4 root root 4096 Sep 17 18:46 ..<\/span><\/p>\n<p><span style=\"color: #cc0000;\">drwxr-xr-x 3 stevee stevee 4096 Sep 18 13:08 .AMD<\/span><\/p>\n<p><span style=\"color: #cc0000;\">-rw------- 1 stevee stevee 3432 Sep 26 20:21 .bash_history<\/span><\/p>\n<p><span style=\"color: #ffffff;\">so grep's search now also includes the total current directory (including hidden) contents in (\/home\/stevee), which also includes the Documents directory anyway! Maybe not what you expect?<\/span><\/p>\n<p><span style=\"color: #ffffff;\">Run it yourself to see. It's only playing with the fundamentals like this, that you will start to think about and start to understand the underlying OS and file system workings, and the tools originally created to manipulate it.<\/span><\/p>\n<p><span style=\"color: #ffffff;\">The Unix engineers really were smart guys, no doubt.<\/span><\/p>\n<p><span style=\"color: #ffffff;\">stevee@AMDA8 ~ $ <span style=\"color: #0000ff;\">ls -ld Documents\/ | grep .* | wc -l<\/span><\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: ..: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .AMD: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .cache: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .cinnamon: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .config: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .dbus: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .gconf: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .gnome: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .gnome2: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .gnome2_private: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .linuxmint: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .local: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .mozilla: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .pki: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .ssh: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">412<\/span><\/p>\n<p><span style=\"color: #cc0000;\"><span style=\"color: #ffffff;\">stevee@AMDA8 ~ $<\/span> <span style=\"color: #0000ff;\">grep .* | wc -l<\/span><\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: ..: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .AMD: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .cache: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .cinnamon: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .config: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .dbus: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .gconf: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .gnome: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .gnome2: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .gnome2_private: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .linuxmint: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .local: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .mozilla: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .pki: Is a directory<\/span><\/p>\n<p><span style=\"color: #cc0000;\">grep: .ssh: Is a directory<\/span><\/p>\n<p><span style=\"color: #ffffff;\"><span style=\"color: #cc0000;\">412<\/span> <\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_2354\" class=\"pvc_stats all  \" data-element-id=\"2354\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/stevepedwards.today\/DebianAdmin\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p>The O_Reilly.pdf pdf of this 1990 book refers to POSIX standard changes in SED etc. so may account for different behaviour by my Mint version of grep, sed and awk etc. from their original examples, as I think happened below. As an introduction to the ideas of iteration and recursion using SED: In simple terms, <a href=\"https:\/\/stevepedwards.today\/DebianAdmin\/sed-basics-using-o_reilly-pdf-example-and-unexpected-mind-bending-parsing-behaviour\/\" class=\"more-link\">...<span class=\"screen-reader-text\">\u00a0 SED Basics using O_Reilly.pdf example, and Unexpected Mind-Bending Parsing Behaviour<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-2354","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"a3_pvc":{"activated":true,"total_views":1,"today_views":0},"_links":{"self":[{"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/posts\/2354","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/comments?post=2354"}],"version-history":[{"count":3,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/posts\/2354\/revisions"}],"predecessor-version":[{"id":10147,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/posts\/2354\/revisions\/10147"}],"wp:attachment":[{"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/media?parent=2354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/categories?post=2354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stevepedwards.today\/DebianAdmin\/wp-json\/wp\/v2\/tags?post=2354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}