<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>sed on Digi Hunch</title><link>https://static.digihunch.com/tag/sed/</link><description>Recent content in sed on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Sat, 20 Jul 2024 16:27:12 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/sed/index.xml" rel="self" type="application/rss+xml"/><item><title>Linux Admin Basics 3 of 3 – text processing, regex, sed &amp; awk</title><link>https://static.digihunch.com/2018/06/text-processing-with-linux-bash/</link><pubDate>Wed, 06 Jun 2018 19:56:00 -0400</pubDate><guid>https://static.digihunch.com/2018/06/text-processing-with-linux-bash/</guid><description>&lt;p class="wp-block-paragraph"&gt;Most of the text processing can be processed by awk and sed. Sed is non-interactive stream editor that allows you to specify all editing instructions in one place and execute them on a single pass through the file. Awk is a pattern-matching programming language.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Using sed and awk requires some understanding of regular expressions. Here&amp;#8217;s the basics of regular expression signs:&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-regular"&gt;&lt;table class="has-background" style="background-color:#e9fbe5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;sign&lt;/td&gt;&lt;td&gt;operation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;^&lt;/td&gt;&lt;td&gt;matches beginning of line&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;$&lt;/td&gt;&lt;td&gt;matches end of line&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.&lt;/td&gt;&lt;td&gt;matches any single character (wildcard)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;*&lt;/td&gt;&lt;td&gt;repeat previous token zero, one or more times.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;+&lt;/td&gt;&lt;td&gt;repeat previous token one or more times&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;?&lt;/td&gt;&lt;td&gt;repeat previous token zero or one time&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;[&amp;#8230;]&lt;/td&gt;&lt;td&gt;matches any one of the class of characters enclosed between the classes.&lt;br&gt; ^ as first character reverses the match&lt;br&gt; &amp;#8211; is used to ndicate a range of characters&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;()&lt;/td&gt;&lt;td&gt;groups regex &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;|&lt;/td&gt;&lt;td&gt;either preceding or following regex can be matched&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;{n,m}&lt;/td&gt;&lt;td&gt;matches a range of occurrences of the single character that immediately precedes it. &lt;br&gt; {n} will match exactly n occurrences&lt;br&gt; {n,} will match at least n occurrences&lt;br&gt; {n,m} will match any number of occurrences between n and m&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Common expressions&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-regular"&gt;&lt;table class="has-background" style="background-color:#e9fbe5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;exp&lt;/td&gt;&lt;td&gt;interpretation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;[^0-9]&lt;/td&gt;&lt;td&gt;excluding number&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;[15]00*&lt;/td&gt;&lt;td&gt;matches &amp;#8220;10&amp;#8221;, &amp;#8220;50&amp;#8221;, &amp;#8220;100&amp;#8221;, &amp;#8220;500&amp;#8221;, &amp;#8220;1000&amp;#8221;, &amp;#8220;5000&amp;#8221;. Here the first 0 is literal, the second is modified by *, see the table above&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.*&lt;/td&gt;&lt;td&gt;any number (including 0) of any character&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;lt;.*&amp;gt;&lt;/td&gt;&lt;td&gt;any html tags&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt; book &lt;/td&gt;&lt;td&gt;matches book with preceding and following spaces&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt; books* &lt;/td&gt;&lt;td&gt;matches books, or book, but not &amp;#8220;book.&amp;#8221; &amp;#8220;book?&amp;#8221; etc&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt; book.* &lt;/td&gt;&lt;td&gt;matches book, followed by any number of characters, or none followed by a space&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Note that regular expression comes in several different flavours, which can be confusing and frustrating. &lt;a href="https://unix.stackexchange.com/questions/119905/why-does-my-regular-expression-work-in-x-but-not-in-y" class="rank-math-link"&gt;This&lt;/a&gt; is a good summary. There are DFA (Deterministic Finite Automata) based engines and NFA (Non-Deterministic Finite Automata) based engines:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;NFA based engines can &amp;#8220;go back&amp;#8221; in the regex, used in Perl, Python, vim, sed and GNU grep.&lt;/li&gt;&lt;li&gt;DFA based engines cannot &amp;#8220;go back&amp;#8221; in the regex, used in awk and BSD grep. &lt;/li&gt;&lt;/ul&gt;&#10;&lt;figure class="wp-block-table"&gt;&lt;table class="has-background" style="background-color:#e9fbe5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Standard&lt;/td&gt;&lt;td&gt;IEEE POSIX&lt;br&gt;BRE&lt;/td&gt;&lt;td&gt;IEEE POSIX&lt;br&gt;ERE&lt;/td&gt;&lt;td&gt;PCRE&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Detail&lt;/td&gt;&lt;td&gt;Basic Regular Expressions&lt;/td&gt;&lt;td&gt;Extended Regular Expressions that add repetition, alternation on top of BRE&lt;/td&gt;&lt;td&gt;Perl Compatible regular expression.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Engine&lt;/td&gt;&lt;td&gt;DFA&lt;/td&gt;&lt;td&gt;DFA&lt;/td&gt;&lt;td&gt;NFA&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GNU grep&lt;/td&gt;&lt;td&gt;grep by default, or grep -G&lt;/td&gt;&lt;td&gt;egrep&lt;br&gt;grep -E&lt;/td&gt;&lt;td&gt;grep -P&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;BSD grep&lt;/td&gt;&lt;td&gt;grep&lt;/td&gt;&lt;td&gt;egrep&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;GNU sed&lt;/td&gt;&lt;td&gt;sed&lt;/td&gt;&lt;td&gt;sed -r&lt;/td&gt;&lt;td&gt;NA. Just use perl&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;BSD sed&lt;/td&gt;&lt;td&gt;sed&lt;/td&gt;&lt;td&gt;sed -E&lt;/td&gt;&lt;td&gt;NA. Just use perl&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;awk&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;awk&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The best way to check isn on &lt;a href="https://www.freebsd.org/cgi/man.cgi" class="rank-math-link"&gt;BSD&lt;/a&gt; manual and &lt;a href="https://www.gnu.org/software/" class="rank-math-link"&gt;GNU&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Here are several examples of sed and awk I came across at work:&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Find and remove duplicate lines:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;awk &amp;#39;!x[$0]++&amp;#39; input_file.txt &amp;gt; output_file.txt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Remove white spaces at the beginning and end of each line:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;awk &amp;#39;{$1=$1}1&amp;#39; input_file.txt &amp;gt; output_file.txt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Print with multiple dilimiters (;, , , and |)&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;awk -F &amp;#39;[;,|]&amp;#39; &amp;#39;{print $1, $3, $5}&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Print with calculation between columns&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;awk &amp;#39;{res=$1-$2;print res,$0}&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Print rows conditionally&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;awk &amp;#39;$1&amp;gt;20{print;}&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Prefix each line of a file&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;awk &amp;#39;$0=&amp;#34;PREFIX|&amp;#34;$0&amp;#39; input.txt &amp;gt; prefix.input.txt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Replace string original to new in file&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sed -i &amp;#39;s/original/new/g&amp;#39; file.txt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Remove multiple patterns&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sed &amp;#39;s/pattern1\|pattern2\|pattern3//g&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Delete the first matching pattern only&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sed &amp;#39;s/pattern//&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Remove blank lines:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sed -i &amp;#39;/^$/d&amp;#39; input_file.txt &amp;gt; output_file.txt&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Copy from line 100 to line 500 of input file to output file&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sed -n 100,500p input.log&amp;gt;output.log&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Merge every three lines:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sed &amp;#39;N;N;N; s/\n/ /g&amp;#39;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2018/05/cron-and-logrotate-in-centos/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;cron and anacron in RedHat Linux (How logrotate works)&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2018/06/dicom-data-encoding/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;DICOM data encoding&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>