{"id":66161,"date":"2022-08-02T09:01:00","date_gmt":"2022-08-02T09:01:00","guid":{"rendered":"https:\/\/www.cryptocabaret.com\/?p=66161"},"modified":"2022-08-02T09:01:00","modified_gmt":"2022-08-02T09:01:00","slug":"how-i-use-the-linux-sed-command-to-automate-file-edits","status":"publish","type":"post","link":"https:\/\/www.cryptocabaret.com\/?p=66161","title":{"rendered":"How I use the Linux sed command to automate file edits"},"content":{"rendered":"<p><span class=\"field field--name-title field--type-string field--label-hidden\">How I use the Linux sed command to automate file edits<\/span><br \/>\n<span class=\"field field--name-uid field--type-entity-reference field--label-hidden\"><a title=\"View user profile.\" href=\"https:\/\/opensource.com\/users\/jim-hall\" class=\"username\">Jim Hall<\/a><\/span><br \/>\n<span class=\"field field--name-created field--type-created field--label-hidden\">Tue, 08\/02\/2022 &#8211; 03:00<\/span><\/p>\n<div data-drupal-selector=\"rate-node-70127\" class=\"rate-widget-thumbs-up\" title=\"Register or Login to like.\">\n<div class=\"rate-thumbs-up-btn-up vote-pending\"><a href=\"https:\/\/opensource.com\/user\/register\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml\">Login<\/a> to like<\/div>\n<div class=\"rate-score\"><a href=\"https:\/\/opensource.com\/user\/register\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml\">Login<\/a> to like<\/div>\n<\/div>\n<div class=\"clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item\">\n<p>When I use the Linux command line, whether I&#8217;m writing a new program on my desktop computer or managing a website on my web server, I often need to process text files. Linux provides powerful tools that I leverage to get my work done. I frequently use <code>sed<\/code>, an editor that can modify text according to a pattern.<\/p>\n<p><code>sed<\/code> stands for <em>stream editor<\/em>, and it edits text in a file and prints the results. One way to use <code>sed<\/code> is to identify several occurrences of one string in a file and replace them with a different string. You can use <code>sed<\/code> to process text files to a seemingly endless degree, but I&#8217;d like to share a few ways I use <code>sed<\/code> to help me manage files.<\/p>\n<h2>Search and replace text in a file on Linux<\/h2>\n<p>To use <code>sed<\/code>, you need to use a <em>regular expression<\/em>. A regular expression is a set of special characters that define a pattern. My most frequent example of using <code>sed<\/code> is replacing text in a file. The syntax for replacing text looks like this: <code>s\/originaltext\/newtext\/<\/code>. The <code>s<\/code> tells sed to perform text replacement or swap occurrences of text. Provide the original text and new text between slashes.<\/p>\n<p>This syntax will only replace the first occurrence of <code>originaltext<\/code> on each line. To replace every occurrence, even if the original text appears more than once on a line, append <code>g<\/code> to the end of the expression. Here is an example: <code>s\/originaltext\/newtext\/g<\/code>.<\/p>\n<p>To use this with <code>sed<\/code>, specify this regular expression with the <code>-e<\/code> option:<\/p>\n<pre>\n<span class=\"geshifilter\"><code class=\"bash geshifilter-bash\"><span class=\"co4\">$ <\/span><span class=\"kw2\">sed<\/span> <span class=\"re5\">-e<\/span> <span class=\"st_h\">'s\/originaltext\/newtext\/g'<\/span><\/code><\/span><\/pre>\n<p>For example, let&#8217;s say I have a Makefile for a program called <strong>game<\/strong>, which simulates Conway&#8217;s Game of Life:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"text geshifilter-text\">.PHONY: all run clean<br><br>\nall: game<br><br>\ngame: game.o<br>\n\u00a0 \u00a0 \u00a0 \u00a0 $(CC) $(CFLAGS) -o game game.o $(LDFLAGS)<br><br>\nrun: game<br>\n\u00a0 \u00a0 \u00a0 \u00a0 .\/game<br><br>\nclean:<br>\n\u00a0 \u00a0 \u00a0 \u00a0 $(RM) *~<br>\n\u00a0 \u00a0 \u00a0 \u00a0 $(RM) *.o<br>\n\u00a0 \u00a0 \u00a0 \u00a0 $(RM) game<\/div><\/div><\/pre>\n<p>The name <strong>game<\/strong> isn&#8217;t very descriptive, so I might choose to rename it <strong>life<\/strong>. Renaming the <code>game.c<\/code> source file to <code>life.c<\/code> is easy enough, but now I need to modify the Makefile to use the new name. I can use <code>sed<\/code> to change every occurrence of <strong>game<\/strong> to <strong>life<\/strong>:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">$ <span class=\"kw2\">sed<\/span> <span class=\"re5\">-e<\/span> <span class=\"st_h\">'s\/game\/life\/g'<\/span> Makefile<br>\n.PHONY: all run clean<br><br>\nall: life<br><br>\nlife: life.o<br>\n\u00a0 \u00a0 \u00a0 \u00a0 $<span class=\"br0\">(<\/span>CC<span class=\"br0\">)<\/span> $<span class=\"br0\">(<\/span>CFLAGS<span class=\"br0\">)<\/span> <span class=\"re5\">-o<\/span> life life.o $<span class=\"br0\">(<\/span>LDFLAGS<span class=\"br0\">)<\/span><br><br>\nrun: life<br>\n\u00a0 \u00a0 \u00a0 \u00a0 .<span class=\"sy0\">\/<\/span>life<br><br>\nclean:<br>\n\u00a0 \u00a0 \u00a0 \u00a0 $<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> <span class=\"sy0\">*<\/span>~<br>\n\u00a0 \u00a0 \u00a0 \u00a0 $<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> <span class=\"sy0\">*<\/span>.o<br>\n\u00a0 \u00a0 \u00a0 \u00a0 $<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> life<\/div><\/div><\/pre>\n<p>This prints the <code>sed<\/code> output to the screen, which is a good way to check if the text replacement will do what you want. To make these changes to the Makefile, first, make a backup of the file, then run <code>sed<\/code> and save the output to the original filename:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">$ <span class=\"kw2\">cp<\/span> Makefile Makefile.old<br>\n$ <span class=\"kw2\">sed<\/span> <span class=\"re5\">-e<\/span> <span class=\"st_h\">'s\/game\/life\/g'<\/span> Makefile.old <span class=\"sy0\">&gt;<\/span> Makefile<\/div><\/div><\/pre>\n<p>If you are confident that your changes are exactly what you want, use the <code>-i<\/code> or <code>--in-place<\/code> option to edit the file in place. However, I recommend adding a backup filename suffix like <code>--in-place=.old<\/code> to save a copy of the original file in case you need to restore it later. It looks like this:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">$ <span class=\"kw2\">sed<\/span> <span class=\"re5\">--in-place<\/span>=.old <span class=\"re5\">-e<\/span> <span class=\"st_h\">'s\/game\/life\/g'<\/span> Makefile<br>\n$ <span class=\"kw2\">ls<\/span> Makefile<span class=\"sy0\">*<\/span><br>\nMakefile \u00a0Makefile.old<\/div><\/div><\/pre>\n<\/p>\n<div class=\"embedded-resource-list callout-float-right\">\n<div class=\"field field--name-title field--type-string field--label-hidden field__item\">More Linux resources<\/div>\n<div class=\"field field--name-links field--type-link field--label-hidden field__items\">\n<div class=\"field__item\"><a href=\"https:\/\/developers.redhat.com\/cheat-sheets\/linux-commands-cheat-sheet\/?intcmp=70160000000h1jYAAQ\">Linux commands cheat sheet<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/developers.redhat.com\/cheat-sheets\/advanced-linux-commands\/?intcmp=70160000000h1jYAAQ\">Advanced Linux commands cheat sheet<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/www.redhat.com\/en\/services\/training\/rh024-red-hat-linux-technical-overview?intcmp=70160000000h1jYAAQ\">Free online course: RHEL technical overview<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/downloads\/cheat-sheet-networking?intcmp=70160000000h1jYAAQ\">Linux networking cheat sheet<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/downloads\/cheat-sheet-selinux?intcmp=70160000000h1jYAAQ\">SELinux cheat sheet<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/downloads\/linux-common-commands-cheat-sheet?intcmp=70160000000h1jYAAQ\">Linux common commands cheat sheet<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/resources\/what-are-linux-containers?intcmp=70160000000h1jYAAQ\">What are Linux containers?<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/tags\/linux?intcmp=70160000000h1jYAAQ\">Our latest Linux articles<\/a><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<h2>Quoting files with sed on Linux<\/h2>\n<p>You can use other features of regular expressions to match specific instances of text. For example, you might need to replace text that occurs at the start of a line. With <code>sed<\/code>, you can match the beginning of a line with <strong>^<\/strong>, the caret character.<\/p>\n<p>One way I use &#8220;start of line&#8221; in replacing text is when I need to quote a file in an email. Let&#8217;s say I want to share my Makefile in an email, but I don&#8217;t want to include it as a file attachment. Instead, I prefer to &#8220;quote&#8221; the file in the body of an email, using <strong>&gt;<\/strong> before each line. I can use the following <code>sed<\/code> command to print out an edited version to my terminal, which I can copy and paste into a new email:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">$ <span class=\"kw2\">sed<\/span> <span class=\"re5\">-e<\/span> <span class=\"st_h\">'s\/^\/&gt;\/'<\/span> Makefile<br><span class=\"sy0\">&gt;<\/span>.PHONY: all run clean<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>all: life<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>life: life.o<br><span class=\"sy0\">&gt;<\/span> \u00a0 \u00a0 \u00a0 $<span class=\"br0\">(<\/span>CC<span class=\"br0\">)<\/span> $<span class=\"br0\">(<\/span>CFLAGS<span class=\"br0\">)<\/span> <span class=\"re5\">-o<\/span> life life.o $<span class=\"br0\">(<\/span>LDFLAGS<span class=\"br0\">)<\/span><br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>run: life<br><span class=\"sy0\">&gt;<\/span> \u00a0 \u00a0 \u00a0 .<span class=\"sy0\">\/<\/span>life<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>clean:<br><span class=\"sy0\">&gt;<\/span> \u00a0 \u00a0 \u00a0 $<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> <span class=\"sy0\">*<\/span>~<br><span class=\"sy0\">&gt;<\/span> \u00a0 \u00a0 \u00a0 $<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> <span class=\"sy0\">*<\/span>.o<br><span class=\"sy0\">&gt;<\/span> \u00a0 \u00a0 \u00a0 $<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> life<\/div><\/div><\/pre>\n<p>The <code>s\/^\/&gt;\/<\/code> regular expression matches the start of each line (<strong>^<\/strong>) and places a <strong>&gt;<\/strong> there. Effectively, this starts each line with the <strong>&gt;<\/strong> symbol.<\/p>\n<p>The tabs might not show up correctly in an email, but I can replace all tabs in the Makefile with a few spaces by adding another regular expression:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">$ <span class=\"kw2\">sed<\/span> <span class=\"re5\">-e<\/span> <span class=\"st_h\">'s\/^\/&gt;\/'<\/span> <span class=\"re5\">-e<\/span> <span class=\"st_h\">'s\/t\/ \u00a0\/g'<\/span> Makefile<br><span class=\"sy0\">&gt;<\/span>.PHONY: all run clean<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>all: life<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>life: life.o<br><span class=\"sy0\">&gt;<\/span> \u00a0$<span class=\"br0\">(<\/span>CC<span class=\"br0\">)<\/span> $<span class=\"br0\">(<\/span>CFLAGS<span class=\"br0\">)<\/span> <span class=\"re5\">-o<\/span> life life.o $<span class=\"br0\">(<\/span>LDFLAGS<span class=\"br0\">)<\/span><br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>run: life<br><span class=\"sy0\">&gt;<\/span> \u00a0.<span class=\"sy0\">\/<\/span>life<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>clean:<br><span class=\"sy0\">&gt;<\/span> \u00a0$<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> <span class=\"sy0\">*<\/span>~<br><span class=\"sy0\">&gt;<\/span> \u00a0$<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> <span class=\"sy0\">*<\/span>.o<br><span class=\"sy0\">&gt;<\/span> \u00a0$<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> life<\/div><\/div><\/pre>\n<p>The <code>t<\/code> indicates a literal tab, so <code>s\/t\/ \/g <\/code>tells sed to replace all tabs in the input with two spaces in the output.<\/p>\n<p>If you need to apply lots of edits to files, you can save your <code>-e<\/code> commands in a file and use <code>-f<\/code> to tell <code>sed<\/code> to use that file as a &#8220;script.&#8221; This approach is especially useful if you need to make the same edits frequently. I might have prepared the Makefile for quoting in email using a script file called <code>quotemail.sed<\/code>:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">$ <span class=\"kw2\">cat<\/span> quotemail.sed<br>\ns<span class=\"sy0\">\/<\/span>^<span class=\"sy0\">\/&gt;\/<\/span><br>\ns<span class=\"sy0\">\/<\/span>t<span class=\"sy0\">\/<\/span> \u00a0<span class=\"sy0\">\/<\/span>g<br>\n$ <span class=\"kw2\">sed<\/span> <span class=\"re5\">-f<\/span> quotemail.sed Makefile<br><span class=\"sy0\">&gt;<\/span>.PHONY: all run clean<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>all: life<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>life: life.o<br><span class=\"sy0\">&gt;<\/span> \u00a0$<span class=\"br0\">(<\/span>CC<span class=\"br0\">)<\/span> $<span class=\"br0\">(<\/span>CFLAGS<span class=\"br0\">)<\/span> <span class=\"re5\">-o<\/span> life life.o $<span class=\"br0\">(<\/span>LDFLAGS<span class=\"br0\">)<\/span><br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>run: life<br><span class=\"sy0\">&gt;<\/span> \u00a0.<span class=\"sy0\">\/<\/span>life<br><span class=\"sy0\">&gt;<\/span><br><span class=\"sy0\">&gt;<\/span>clean:<br><span class=\"sy0\">&gt;<\/span> \u00a0$<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> <span class=\"sy0\">*<\/span>~<br><span class=\"sy0\">&gt;<\/span> \u00a0$<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> <span class=\"sy0\">*<\/span>.o<br><span class=\"sy0\">&gt;<\/span> \u00a0$<span class=\"br0\">(<\/span>RM<span class=\"br0\">)<\/span> life<\/div><\/div><\/pre>\n<h2>Learn to work with sed on Linux<\/h2>\n<p><code>sed<\/code> is a great tool to keep in your Linux command-line toolkit. Explore the <code>sed<\/code> manual page and learn more about how to use it. Type <code>man sed<\/code> at the command line to get complete documentation about the different command line options and how to use <code>sed<\/code> to process text files.<\/p>\n<\/div>\n<div class=\"clearfix text-formatted field field--name-field-article-subhead field--type-text-long field--label-hidden field__item\">\n<p>Here are some tips and tricks to automating file edits from the Linux command line.<\/p>\n<\/div>\n<div class=\"field field--name-field-lead-image field--type-entity-reference field--label-hidden field__item\">\n<article class=\"media media--type-image media--view-mode-caption\">\n<div class=\"field field--name-field-media-image field--type-image field--label-hidden field__item\">  <img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.cryptocabaret.com\/wp-content\/uploads\/2022\/08\/features_solutions_command_data.png\" width=\"520\" height=\"293\" alt=\"computer screen \" title=\"computer screen \"><\/div>\n<div class=\"field field--name-field-caption field--type-text-long field--label-hidden caption field__item\"><span class=\"caption__byline\">Image by: <\/span><\/p>\n<p>Opensource.com<\/p>\n<\/div>\n<\/article>\n<\/div>\n<div class=\"field field--name-field-tags field--type-entity-reference field--label-hidden field__items\">\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/tags\/linux\" hreflang=\"en\">Linux<\/a><\/div>\n<\/p><\/div>\n<div class=\"hidden field field--name-field-listicle-title field--type-string field--label-hidden field__item\">What to read next<\/div>\n<div class=\"field field--name-field-default-license field--type-list-string field--label-hidden field__item\"><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\"><br \/>\n        <img decoding=\"async\" alt=\"Creative Commons License\" src=\"https:\/\/www.cryptocabaret.com\/wp-content\/uploads\/2022\/08\/cc-by-sa-4-2.png\" title=\"This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.\"><\/a>This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.<\/div>\n<section class=\"field field--name-field-comments field--type-comment field--label-hidden comment-wrapper\">\n<div class=\"comments__count\">\n<div class=\"login\"><a href=\"https:\/\/opensource.com\/user\/register?absolute=1\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml&amp;absolute=1\">Login<\/a> to post a comment.<\/div>\n<\/p><\/div>\n<\/section>\n<p class=\"wpematico_credit\"><small>Powered by <a href=\"http:\/\/www.wpematico.com\" target=\"_blank\" rel=\"noopener\">WPeMatico<\/a><\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How I use the Linux sed command to automate file edits Jim Hall Tue, 08\/02\/2022 &#8211; 03:00 Register or Login to like Register or Login to like When I use the Linux command line, whether I&#8217;m writing a new program on my desktop computer or managing a website on my web server, I often need [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":66162,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[307],"tags":[],"class_list":["post-66161","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-open-source"],"_links":{"self":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts\/66161","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=66161"}],"version-history":[{"count":0,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts\/66161\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/media\/66162"}],"wp:attachment":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=66161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=66161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=66161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}