{"id":222,"date":"2020-08-18T19:23:47","date_gmt":"2020-08-18T20:23:47","guid":{"rendered":"http:\/\/www.linux-tutorial.info\/?page_id=77"},"modified":"2020-08-22T19:26:19","modified_gmt":"2020-08-22T20:26:19","slug":"this-is-the-page-title-toplevel-57","status":"publish","type":"page","link":"http:\/\/www.linux-tutorial.info\/?page_id=222","title":{"rendered":"Sed"},"content":{"rendered":"\n<title>Sed<\/title>\n<p>\nSuppose you have a file in which you need to make some changes. You could load up vi and make the changes\nthat way, but what if what you wanted to change was the output of some command before you sent it to a file? You could\nfirst send it to a file and then edit that file, or you could use sed, which is a <u>s<\/u>tream <u>ed<\/u>itor that is specifically\ndesigned to edit data <glossary>streams<\/glossary>.\n <\/p>\n<p>\nIf you read the previous section or are already familiar with either the search and replace mechanisms in vi or the editor\ned, you already have a jump on learning sed. Unlike vi, sed is non-interactive, but can handle more complicated editing\ninstructions. Because it is non-interactive, commands can be saved in text\nfiles and used over and over. This makes debugging the more complicated sed constructs much easier. For the most part,\nsed is line-oriented, which allows it to process files of almost any size. However, this has the disadvantage that sed cannot do\nediting that is dependent on relative addressing.\n<\/p>\n<p>\nUnlike the section on vi, I am not going to go into as many details about sed. However, sed is a useful tool and I use it often.\nThe reason I am not going to cover it in too much detail is three-fold. First, much of what is true about pattern searches,\naddressing, etc., in vi is also true in sed. Therefore, I don&#8217;t feel the need to repeat. Second, it is not that important that you\nbecome a sed expert to be a good system <glossary>administrator<\/glossary>.\n In a few cases, scripts on a Linux system will use sed. However, they are not that difficult to understand, provided you have a\n basic understanding of sed syntax. Third, sed is like any programming language, you can get by with simple things. However, to\n get really good, you need to practice and we just don&#8217;t have the space to go beyond the basics.\n<\/p>\n<p>\nIn this section, I am going to talk about the basics of sed syntax, as well as some of the more common sed commands and\nconstructs. If you want to learn more, I recommend getting <i>sed &amp; awk<\/i>by Dale Dougherty from O&#8217;Reilly and\n Associates. This will also help you in the section on awk, which is coming up next.\n<\/p>\n<p>\nThe way sed works is that it reads input one line at a time, and then carries out whatever editing changes you specify.\nWhen it has finished making the changes, it writes them to <glossary>stdout<\/glossary>.\n Like commands such as grep and sort, sed acts like a filter. However, with sed you can create very complicated programs.\n Because I normally use sed as one end of a <glossary>pipe<\/glossary>,\n most of the sed commands  that I use have the following structure:\n<\/p>\n<p>\n<commandexample command=\"sed\">first_cmd | sed &lt;options&gt; &lt;edit_description&gt; <\/commandexample>\n<\/p>\n<p>\nThis is useful when the edit descriptions you are using are fairly simple. However, if you want to perform multiple edits on\neach line, then this way is not really suitable. Instead, you can put all of your changes into one file and start up sed like this\n<\/p>\n<p>\n<commandexample command=\"sed\">first_cmd | sed -f editscript <\/commandexample>\n<\/p>\n<p>\nor\n<\/p>\n<p>\n<commandexample command=\"sed\">sed -f editscript &lt;inputfile<\/commandexample>\n<\/p>\n<p>\nAs I mentioned before, the addressing and search\/replace mechanisms within sed are basically the same as within vi.\nIt has the structure\n<\/p>\n<p>\n<commandexample>[address1[,address2]] edit_description [arguments]  <\/commandexample>\n<\/p>\n<p>\nAs with vi, addresses do not necessarily need to be line numbers, but can be regular expressions that sed needs to search\nfor. If you omit the <glossary>address<\/glossary>,\nsed will make the changes globally, as applicable. The  edit_description tells sed what changes to make. Several arguments\ncan be used, and we&#8217;ll get to them as we move along.\n<\/p>\n<p>\nAs sed reads the file, it copies each line into its <em>pattern space<\/em>. This pattern space is a special\n<glossary>buffer<\/glossary>\nthat sed uses to hold a line of text\nas it processes it. As soon as it has finished reading the line, sed begins to apply the changes to the pattern space based on\nthe edit description.\n<\/p>\n<p>\nKeep in mind that even though sed will read a line into the pattern space,  it will only make changes to addresses that match\nthe addresses specified and does not print any warnings when this happens. In general, sed either silently ignores errors or\nterminates abruptly with an <glossary>error message<\/glossary>\nas a result of a syntax error, not because there we no matches. If there are no lines that contain the pattern, no lines match,\nand the edit commands are not carried out.\n<\/p>\n<p>\nBecause you can have multiple changes on any given line, sed will carry them each out in turn. When there are no more\nchanges to be made, sed sends the result to its output. The next line is read in and the whole process starts over. As it reads\nin each line, sed will increment an internal line counter, which keeps track of the <em>total<\/em> number of lines read, not lines\nper file. This is an important distinction if you have multiple files that are being read. For example, if you had two 50-line files, from\nsed&#8217;s perspective, line 60 would be the tenth line in the second file.\n<\/p>\n<p>\nEach sed command can have 0, 1, or 2 addresses. A command with no addresses specified is applied to every line in the\ninput. A command with one <glossary>address<\/glossary>\nis applied to all lines that match that address. For example:<\/p>\n<p>\n<commandexample>\/mike\/s\/fred\/john\/  <\/commandexample>\n<\/p>\n<p>\nsubstitutes the first instance of &#8220;john for &#8220;fred only on those lines containing &#8220;mike. A command with two addresses is\napplied to the first line that matches the first <glossary>address<\/glossary>,\n then to all subsequent lines until a match for the second address is processed. An attempt is made to match the first address\n on subsequent lines, and the process is repeated. Two addresses are separated by a comma.\n<\/p>\n<p>\nFor example\n<\/p>\n<p>\n<commandexample>50,100s\/fred\/john\/<\/commandexample>\n<\/p>\n<p>\nsubstitutes the first instance of &#8220;john for &#8220;fred from line 50 to line 100, inclusive. (Note that there should be no space\nbetween the second <glossary>address<\/glossary>\nand the s command.) If an address is followed by an exclamation mark (!), the command is applied only to lines that do not\nmatch the address. For example\n<\/p>\n<p>\n<commandexample>50,100!s\/fred\/john\/<\/commandexample>\n<\/p>\n<p>\nsubstitutes the first instance of &#8220;john for &#8220;fred everywhere except lines 50 to 100, inclusive.\n<\/p>\n<p>\nAlso, sed can be told to do input and output based on what it finds. The action it should perform is identified by an\n<glossary>argument<\/glossary>\nat the end of the sed command. For example, if we wanted to print out lines 5-10 of a specific file, the sed command\nwould be\n<\/p>\n<p>\n<commandexample command=\"sed\">cat file | sed -n 5,10p<\/commandexample>\n<\/p>\n<p>\nThe -n is necessary so that every line isn&#8217;t output in <i>addition<\/i> to the lines that match.\n<\/p>\n<p>\nRemember the script we created in the first section of this chapter, where we wanted just lines 510 of every file. Now\nthat we know how to use sed, we can change the script to be a lot more efficient. It would now look like this:<\/p>\n<p>\n<commandexample command=\"sed\">\nfind .\/letters\/taxes -print | while read FILE\ndo\necho $FILE\ncat $FILE |  sed -n 5-10p\ndone\n<\/commandexample>\n<br \/>\n<p>\nRather than sending the file through head and then the output through tail, we send the whole file through\nsed. It can keep track of which line is line 1, and then print the necessary lines.\n<\/p>\n<p>\nIn addition, sed allows you to write lines that match. For example, if we wanted all the comments in a\nshell script to be output to a file, we could use sed like this:<\/p>\n<p>\n<commandexample command=\"sed\">cat filename |  sed -n \/^#\/w filename<\/commandexample>\n<\/p>\n<p>\nNote that there must be exactly one space between the w and the name of the file. If we wanted to read in a file, we could\ndo that as well. Instead of a <kbd>w<\/kbd> to write, we could use an <kbd>r<\/kbd> to read. The contents of the file would be appended\nafter the lines specified in the <glossary>address<\/glossary>.\n Also keep in mind that writing to or reading from a file are independent of what happens next. For example, if we write every line\n in a file containing the name &#8220;John,&#8221; but in a subsequent <command>sed<\/command> command change &#8220;John&#8221; to &#8220;Chris,&#8221; the file would contain\n references to &#8220;John,&#8221; as no changes are made. This is logical because <command>sed<\/command> works on each line and the lines are\n already in the file before the changes are made.\n<\/p>\n<p>\nKeep in mind that every time a line is read in, the contents of the pattern space are overwritten. To save certain data across\nmultiple commands, sed provides what is called the &#8220;hold space.&#8221; Changes are not made to the hold space directly, rather the\ncontents of either one can be copied into the other for processes. The contents can even be exchanged, if needed.\nThe table below\ncontains a list of the more common <command>sed<\/command> commands, including the commands used to manipulate the hold and pattern spaces.\n<\/p>\n<b>\n<p>\nTable <\/a> sed Commands<\/a>\n<\/p><\/b>\n<p align=\"CENTER\"><center>\n<table BORDER cellspacing=1 bordercolor=\"#000000\" cellpadding=7 WIDTH=411>\n<tr><td>\n<p>\na<\/td>\n<td>\n<p>\nappend text to the pattern space<\/td>\n<\/tr>\n<tr><td>\n<p>\nb<\/td>\n<td>\n<p>\nbranch to a label<\/td>\n<\/tr>\n<tr><td>\n<p>\nc<\/td>\n<td>\n<p>\nappend text<\/td>\n<\/tr>\n<tr><td>\n<p>\nd<\/td>\n<td>\n<p>\ndelete text<\/td>\n<\/tr>\n<tr><td>\n<p>\nD<\/td>\n<td>\n<p>\ndelete all the characters from the start of the pattern space up to and including the first new line<\/td>\n<\/tr>\n<tr><td>\n<p>\ng<\/td>\n<td>\n<p>\noverwrite the pattern space with the holding area <\/td>\n<\/tr>\n<tr><td>\n<p>\nG<\/td>\n<td>\n<p>\nappends the holding area to the pattern space, separated with a new line<\/td>\n<\/tr>\n<tr><td>\n<p>\nh<\/td>\n<td>\n<p>\noverwrite holding area with pattern space<\/td>\n<\/tr>\n<tr><td>\n<p>\nH<\/td>\n<td>\n<p>\nappend\n<\/p>\n<p>\ns the pattern space to the holding area, separated\n<\/p>\n<p>\nby a newlinewith a new line<\/td>\n<\/tr>\n<tr><td>\n<p>\ni<\/td>\n<td>\n<p>\ninsert text<\/td>\n<\/tr>\n<tr><td>\n<p>\nl<\/td>\n<td>\n<p>\nlist the contents of the pattern space<\/td>\n<\/tr>\n<tr><td>\n<p>\nn<\/td>\n<td>\n<p>\nadd a new line to the pattern space<\/td>\n<\/tr>\n<tr><td>\n<p>\nN<\/td>\n<td>\n<p>\nappend the next input line to the pattern space, separated lines with a new line<\/td>\n<\/tr>\n<tr><td>\n<p>\np<\/td>\n<td>\n<p>\nprint the pattern space<\/td>\n<\/tr>\n<tr><td>\n<p>\nP<\/td>\n<td>\n<p>\nprint from the start of the pattern space up to and including the first new line<\/td>\n<\/tr>\n<tr><td>\n<p>\nr<\/td>\n<td>\n<p>\nread in a file<\/td>\n<\/tr>\n<tr><td>\n<p>\ns<\/td>\n<td>\n<p>\nsubstitute patterns<\/td>\n<\/tr>\n<tr><td>\n<p>\nt<\/td>\n<td>\n<p>\nbranch only if a substitution has been made to the current pattern space<\/td>\n<\/tr>\n<tr><td>\n<p>\nw<\/td>\n<td>\n<p>\nwrites to a file<\/td>\n<\/tr>\n<tr><td>\n<p>\nx<\/td>\n<td>\n<p>\ninterchange the contents of the pattern space and the holding area (the maximum number of addresses is two)<\/td>\n<\/tr>\n<\/table>\n<\/center>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sed Suppose you have a file in which you need to make some changes. You could load up vi and make the changes that way, but what if what you wanted to change was the output of some command before &hellip; <a href=\"http:\/\/www.linux-tutorial.info\/?page_id=222\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-222","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/222","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=222"}],"version-history":[{"count":1,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/222\/revisions"}],"predecessor-version":[{"id":694,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/222\/revisions\/694"}],"wp:attachment":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=222"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}