<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Waqar Ahmed</title>
    <description>The latest articles on Forem by Waqar Ahmed (@waqar).</description>
    <link>https://forem.com/waqar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F579246%2F3f235ae6-7946-47f8-b113-73b18cf7a62b.png</url>
      <title>Forem: Waqar Ahmed</title>
      <link>https://forem.com/waqar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/waqar"/>
    <language>en</language>
    <item>
      <title>Getting Started with Git</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Mon, 08 Apr 2024 11:42:51 +0000</pubDate>
      <link>https://forem.com/waqar/getting-started-with-git-pjg</link>
      <guid>https://forem.com/waqar/getting-started-with-git-pjg</guid>
      <description>&lt;h2&gt;
  
  
  What is Git?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Snapshots, Not Differences
&lt;/h3&gt;

&lt;p&gt;The major difference between Git and any other VCS is that Git stores snapshots, while other system store file differences.&lt;/p&gt;

&lt;p&gt;Most other versioning systems store data as changes to a base version of each file. However. Git stores data as snapshots of the project over time.&lt;/p&gt;

&lt;p&gt;Git thinks of its data more like a series of snapshots of a miniature filesystem. With Git, every time you commit, or save the state of your project, Git basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot.&lt;/p&gt;

&lt;p&gt;To be efficient, if files have not changed, Git doesn’t store the file again, just a link to the previous identical file it has already stored. Git thinks about its data more like a &lt;strong&gt;stream of snapshots&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nearly Every Operation Is Local
&lt;/h3&gt;

&lt;p&gt;Most operations in Git need only local files and resources to operate — generally no information is needed from another computer on your network.&lt;/p&gt;

&lt;p&gt;Git simply reads project data directly from your local database, no server access is necessary. This also means that there is very little you can’t do if you’re offline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git Has Integrity
&lt;/h3&gt;

&lt;p&gt;Everything in Git is checksummed (SHA-1 hash) before it is stored and is then referred to by that checksum.  So, any change in file or directory structure will change its checksum, which is detected by Git. This means it’s impossible to change the contents of any file or directory without Git knowing about it.&lt;/p&gt;

&lt;p&gt;You can’t lose information in transit or get file corruption without Git being able to detect it.&lt;/p&gt;

&lt;p&gt;Git stores everything in its database not by file name but by the hash value of its contents.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git Generally Only Adds Data
&lt;/h3&gt;

&lt;p&gt;When you do actions in Git, nearly all of them only &lt;em&gt;add&lt;/em&gt; data to the Git database.&lt;br&gt;
As with any VCS, you can lose or mess up changes you haven’t committed yet, but after you commit a snapshot into Git, it is very difficult to lose.  Especially if you regularly push your database to another repository&lt;/p&gt;

&lt;h3&gt;
  
  
  The Three States Of Git
&lt;/h3&gt;

&lt;p&gt;Git has three main states that your files can reside in: &lt;strong&gt;&lt;em&gt;modified&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;staged&lt;/em&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;em&gt;committed&lt;/em&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Modified means that you have changed the file but have not committed it to your database yet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Staged means that you have marked a modified file in its current version to go into your next commit snapshot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Committed means that the data is safely stored in your local database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leads us to the three main sections of a Git project: the working tree, the staging area, and the Git directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyvojpfofd8l3jg27jwwr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyvojpfofd8l3jg27jwwr.png" alt="Working tree, staging area, and Git directory (source: git-scm.com)&amp;lt;br&amp;gt;
" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Working tree, staging area, and Git directory (source: git-scm.com)&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;The working tree is a single checkout of one version of the project. These files are pulled out of the compressed database in the Git directory and placed on disk for you to use or modify.&lt;/p&gt;

&lt;p&gt;The staging area is a file, generally contained in your Git directory, that stores information about what will go into your next commit. Its technical name in Git parlance is the “index”, but the phrase “staging area” works just as well.&lt;/p&gt;

&lt;p&gt;The Git directory is where Git stores the metadata and object database for your project. This is the most important part of Git, and it is what is copied when you &lt;em&gt;clone&lt;/em&gt; a repository from another computer.&lt;/p&gt;

&lt;p&gt;The basic Git workflow goes something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You modify files in your working tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You selectively stage just those changes you want to be part of your next commit, which adds &lt;em&gt;only&lt;/em&gt; those changes to the staging area.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You do a commit, which takes the files as they are in the staging area and stores that snapshot permanently to your Git directory.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the second article of this series, I will post about Git installation and configurations. The third would be about Git basics and getting a Git repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;: &lt;a href="https://waqar.org/getting-started-with-git" rel="noopener noreferrer"&gt;waqar.org/getting-started-with-git&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Chacon, S. and Straub, B. (2014) &lt;em&gt;Pro Git&lt;/em&gt;. 2nd ed. Berlin, Germany: APress.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Book&lt;/em&gt; (2014) &lt;em&gt;Git-scm.com&lt;/em&gt;. Available at: &lt;a href="https://git-scm.com/book/en/v2/" rel="noopener noreferrer"&gt;https://git-scm.com/book/en/v2/&lt;/a&gt; (Accessed: March 22, 2024).&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>gitcommand</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>9 Essential commands to unlock the power of vim</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Mon, 09 Aug 2021 11:58:49 +0000</pubDate>
      <link>https://forem.com/waqar/9-essential-commands-to-unlock-the-power-of-vim-3ooh</link>
      <guid>https://forem.com/waqar/9-essential-commands-to-unlock-the-power-of-vim-3ooh</guid>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Bram_Moolenaar" rel="noopener noreferrer"&gt;Bram Moolenaar&lt;/a&gt; , the creator of vim, cloned and improved vi and released it in 1991. The name vim came from "vi imitations", later changed to "Vi improved". Gradually it became the most popular text editor among Linux users. In 2019 Stackoverflow developers  &lt;a href="https://insights.stackoverflow.com/survey/2019#development-environments-and-tools" rel="noopener noreferrer"&gt;survey&lt;/a&gt;  vim was the fourth most popular text editor.&lt;/p&gt;

&lt;p&gt;In their last survey, Stackoverflow revealed over 2.1 million people visited the ' &lt;a href="https://stackoverflow.com/questions/11828270/how-do-i-exit-the-vim-editor" rel="noopener noreferrer"&gt;How do I exit the Vim editor?&lt;/a&gt; ' question on Stack Overflow. So I am writing some top googled vim commands and the general know-how required to use vim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vim modes
&lt;/h2&gt;

&lt;p&gt;Out of so many, the most frequently used are "command-line mode", "normal mode" and "insert mode".&lt;/p&gt;

&lt;h3&gt;
  
  
  Normal mode
&lt;/h3&gt;

&lt;p&gt;You are in normal mode when you open a file. To go back to the "normal mode", press the &lt;code&gt;Esc&lt;/code&gt; key.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command-line mode
&lt;/h3&gt;

&lt;p&gt;To run a command, go to the command-line mode by typing colon &lt;code&gt;:&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Insert mode
&lt;/h3&gt;

&lt;p&gt;Get into "insert mode" by pressing &lt;code&gt;i&lt;/code&gt; in "normal mode".&lt;/p&gt;

&lt;h2&gt;
  
  
  Vim commands
&lt;/h2&gt;

&lt;p&gt;Press &lt;code&gt;Esc&lt;/code&gt; key to enter "normal mode" then press colon &lt;code&gt;:&lt;/code&gt; to enter "command-line mode". At the bottom left corner of vim, a  colon &lt;code&gt;:&lt;/code&gt; appears. Now you can type any command and press the &lt;code&gt;Enter&lt;/code&gt; key to execute the command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vim command to open a file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Type vim preceded by file name to open a file in the vim text editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vim command to save and exit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Press the &lt;code&gt;Esc&lt;/code&gt; to get out of "insert mode". Press colon &lt;code&gt;:&lt;/code&gt; to get into the "command-line mode" and type &lt;code&gt;wq&lt;/code&gt; to write and quit the file.  If you have not made any changes to the file, you can exit by &lt;code&gt;q&lt;/code&gt; command.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;:q&lt;/code&gt; to quit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:wq&lt;/code&gt; to write and quit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:q!&lt;/code&gt; to quit without writing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:x&lt;/code&gt; to save and quit (similar to :wq)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:exit&lt;/code&gt; save and exit (similar to :x)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;vim command to edit file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Press the &lt;code&gt;i&lt;/code&gt; key in "normal mode" to start editing the file. Move around with arrow keys or use these keys:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;l&lt;/code&gt; move right&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;k&lt;/code&gt; move up&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;j&lt;/code&gt; move down&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;h&lt;/code&gt; move left&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;vim command to go to the end of the file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Type capital &lt;code&gt;G&lt;/code&gt; or &lt;code&gt;shift+g&lt;/code&gt; to go to the end of the file in vim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vim command to go to top of file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Type &lt;code&gt;gg&lt;/code&gt; or &lt;code&gt;1G&lt;/code&gt; to go to the beginning of the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vim command to delete all lines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use letter &lt;code&gt;d&lt;/code&gt; to delete. Go into "command-line mode" by pressing &lt;code&gt;:&lt;/code&gt; and type &lt;code&gt;%d&lt;/code&gt; to delete all lines. You can also use range &lt;code&gt;1,$d&lt;/code&gt;. Just like regular expressions &lt;code&gt;$&lt;/code&gt; sign represents the end of the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vim command to show line numbers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In "command-line mode" type, &lt;code&gt;set numbers&lt;/code&gt; or short command &lt;code&gt;set nu&lt;/code&gt; to display line numbers of the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vim command to replace string&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Type search string followed by the replacement string &lt;code&gt;%s/search/replace/g&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vim command to delete lines with pattern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside "command-line mode" type, &lt;code&gt;g/pattern/d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Run the &lt;code&gt;:help&lt;/code&gt; command to check usage documentation. Add a query after &lt;code&gt;:help&lt;/code&gt; to get specific help. Vim comes with a separate tutor program to teach vim usage. Run &lt;code&gt;vimtutor&lt;/code&gt; in the terminal for this 20 minutes practice tutorial. Use the comments section to mention any other essential commands that I have missed.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>linux</category>
      <category>programming</category>
    </item>
    <item>
      <title>Bootstrap VS Tachyons</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Wed, 30 Jun 2021 17:13:45 +0000</pubDate>
      <link>https://forem.com/waqar/bootstrap-vs-tachyons-ip0</link>
      <guid>https://forem.com/waqar/bootstrap-vs-tachyons-ip0</guid>
      <description>&lt;p&gt;Compared to Tachyons, Bootstrap is higher level framework, but Bootstrap is heavy. Bootstraps &lt;code&gt;btn&lt;/code&gt; class adds over 400 lines of CSS code to the HTML element.&lt;br&gt;
Customisation of Bootstrap is frustrating. To change the look and feel of Twitter, one would need to look into long pages of code adding even more lines and probably many !important directives.&lt;br&gt;
Dakota Lee Martinez in his &lt;a href="https://medium.com/@dakotaleemartinez/keeping-your-css-dry-with-tachyons-bb1c0dc66dce" rel="noopener noreferrer"&gt;article&lt;/a&gt; provides a button example created with &lt;a href="https://tachyons.io/" rel="noopener noreferrer"&gt;Tachyons&lt;/a&gt;, which is elegant and simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; 
&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pa2 bg-light-gray link ba bw1 bg-hover-moon-gray black br3"&lt;/span&gt; 
&lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
Link Button
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above code adds padding with class pa2, light grey background with bg-light-gray, link class removes hyperlink’s underline, class ba adds border and its width is set by bw1, bg-hover-moon-gray changes background on hover.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tachyons Vs Bootstrap in the eyes of developers
&lt;/h3&gt;

&lt;p&gt;In a comment of stackshare Bridget Sarah says Bootstrap is pain to override and you can tell from distance if you are using Bootstrap as every thing looks similar. She has found &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt; CSS, which she finds better and faster than Bootstrap.&lt;br&gt;
According to &lt;a href="http://tachyons.io/#testimonials" rel="noopener noreferrer"&gt;Daniel Eden&lt;/a&gt;, Designer at Facebook, Tachyons documents and limits properties of components which he calls subatomic design. These subatomic properties are composed to create components, rather than recreating components and its variants.&lt;/p&gt;

&lt;p&gt;Tachyons developer, &lt;a href="http://mrmrs.cc/" rel="noopener noreferrer"&gt;Adam Morse&lt;/a&gt; in this &lt;a href="https://www.youtube.com/watch?v=r56fRaWth58" rel="noopener noreferrer"&gt;talk&lt;/a&gt; at DevShop London 2016, talks about motivation behind Tachyons. He discusses the problem of continuous over-riding your own written CSS code, writing tons of CSS code, struggle to keep all this info in your head and the need to refactor 200Kb CSS file. His answer to the problem is Tachyons. &lt;a href="https://suitcss.github.io/" rel="noopener noreferrer"&gt;SUIT CSS&lt;/a&gt; (Style Tools for UI Components). was the initial inspiration that lead to creation of Tachyons. Unlike Bootstrap where you redefine a component multiple times, SUIT had a class which would not redefine itself or mutate later.&lt;/p&gt;
&lt;h3&gt;
  
  
  Tachyons Primer
&lt;/h3&gt;

&lt;p&gt;Tachyons CSS Grids and Colour&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sQDvGgWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1625071759937/YOQFmVR4x.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sQDvGgWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1625071759937/YOQFmVR4x.jpeg" alt="tachyons-grid-css.jpg" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VJTJ488Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1625071789917/iFBeCKICR.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VJTJ488Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1625071789917/iFBeCKICR.jpeg" alt="tachyons-color-css.jpg" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To find more classes check &lt;a href="http://tachyons.io/components/" rel="noopener noreferrer"&gt;Tachyons Styles&lt;/a&gt; page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://roperzh.github.io/tachyons-cheatsheet/" rel="noopener noreferrer"&gt;Cheatsheet&lt;/a&gt; with colours and relevant class names for text, backgrounds and borders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some friendly &lt;a href="https://tachyons.io/docs/themes/skins/" rel="noopener noreferrer"&gt;colour combinations&lt;/a&gt; by Tachyons.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Tachyons Installation and usage
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;CDN&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quickest and easiest method is to include tahyons in HTML head section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/tachyons@4.10.0/css/tachyons.min.css"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NPM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check &lt;a href="https://www.npmjs.com/package/tachyons" rel="noopener noreferrer"&gt;Tacyons npm&lt;/a&gt; or simply run following.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save-dev tachyons@4.10.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or use Git repo and build locally&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com:tachyons-css/tachyons.git
&lt;span class="nb"&gt;cd &lt;/span&gt;tachyons
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Automate server intrusion detection and banning with Fail2ban</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Tue, 29 Jun 2021 18:23:31 +0000</pubDate>
      <link>https://forem.com/waqar/automate-server-intrusion-detection-and-banning-with-fail2ban-4pgk</link>
      <guid>https://forem.com/waqar/automate-server-intrusion-detection-and-banning-with-fail2ban-4pgk</guid>
      <description>&lt;p&gt;A Fail2Ban installation monitors server access logs and automatically bans IP addresses of bots and attacking users in iptables. Fail2Ban analyses server logs and identifies a pattern where a suspicious user or bot is trying to access restricted areas on the server. Brute force attacks repeatedly fail and use combinations of login credentials on after another. Fail to ban can detect failed login attempts on SSH and Apache webserver.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fail2Ban Installation
&lt;/h2&gt;

&lt;p&gt;Installation is straight forward update &lt;code&gt;apt-get&lt;/code&gt; and run instal fail2ban as a root user. Theses are Debian/Ubuntu commands for CentOS &lt;code&gt;yum&lt;/code&gt; would replace &lt;code&gt;apt-get&lt;/code&gt; and paths/locations might differ for configuration files. Check &lt;a href="https://www.linode.com/docs/security/using-fail2ban-to-secure-your-server-a-tutorial/" rel="noopener noreferrer"&gt;this&lt;/a&gt; tutorial for non-Debian operating systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fail2Ban Configuration
&lt;/h2&gt;

&lt;p&gt;Fail2Ban can keep server admin updated with emails but to keep it simple, let’s not configure this additional feature. The configuration file /etc/fail2ban/fail2ban.conf is superseded by fail2ban.local file. So this local config file needs to be created to keep additional settings. Here is part of the default installation config file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Definition]&lt;/span&gt;
&lt;span class="c"&gt;# Option: loglevel
# Notes.: Set the log level output.
#         CRITICAL
#         ERROR
#         WARNING
#         NOTICE
#         INFO
#         DEBUG
# Values: [ LEVEL ]  Default: ERROR
#
&lt;/span&gt;&lt;span class="py"&gt;loglevel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;INFO&lt;/span&gt;
&lt;span class="py"&gt;logtarget&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/var/log/fail2ban.log&lt;/span&gt;
&lt;span class="c"&gt;# Options: dbfile
# Notes.: Set the file for the fail2ban persistent data to be stored.
#         A value of ":memory:" means database is only stored in memory 
#         and data is lost when fail2ban is stopped.
#         A value of "None" disables the database.
# Values: [ None :memory: FILE ] Default: /var/lib/fail2ban/fail2ban.sqlite3
&lt;/span&gt;&lt;span class="py"&gt;dbfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/var/lib/fail2ban/fail2ban.sqlite3&lt;/span&gt;
&lt;span class="c"&gt;# Options: dbpurgeage
# Notes.: Sets age at which bans should be purged from the database
# Values: [ SECONDS ] Default: 86400 (24hours)
&lt;/span&gt;&lt;span class="py"&gt;dbpurgeage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;86400&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fail2ban focuses on failed SSH login attempts by default. Using custom config file jails for HTTP web server like Apache, FTP and mail server can be enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fail2Ban Apache Jail Configuration
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[apache-auth]&lt;/span&gt;
&lt;span class="py"&gt;enabled&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;span class="py"&gt;logpath&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/var/log/apache2/error.log&lt;/span&gt;
&lt;span class="py"&gt;maxretry&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;3&lt;/span&gt;
&lt;span class="py"&gt;findtime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;600&lt;/span&gt;
&lt;span class="py"&gt;bantime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here we have set up fail2ban to look apache2 error logs for brute force attack using one password after another. Three failed login attempts within 600 seconds would lead to an IP address ban for an hour. Restart fail2ban for the changes to take effect sudo systemctl restart fail2ban. To enable fail2ban service to start with boot use sudo systemctl enable fail2ban.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Apache error log jails
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Apache no script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[apache-noscript]&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;span class="py"&gt;logpath&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;%(apache_error_log)s&lt;/span&gt;
&lt;span class="py"&gt;ignoreip&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;localhost or an IP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fail2ban analyses errors of not found .php, .asp, .pl scripts. Client attempting to exploit known scripts are banned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache overflows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[apache-overflows]&lt;/span&gt;
&lt;span class="py"&gt;logpath&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;%(apache_error_log)s&lt;/span&gt;
&lt;span class="py"&gt;maxretry&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Detects apache buffer overflow attempts by the client using long suspicious URLs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache no home
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[apache-nohome]&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Detects failures to find a home directory on a server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache bot search
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[apache-botsearch]&lt;/span&gt;
&lt;span class="py"&gt;enabled&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;span class="py"&gt;maxretry&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternative to apache-noscript filter this filter aims at blocking specific URLs, script or webservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache access log jails
&lt;/h3&gt;

&lt;p&gt;Beware, access logs of busy websites can be huge. Setting Fail2ban to monitor access log can have a negative impact on server performance. So think about costs and benefits of access log jails before enabling them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache bad bots
&lt;/h3&gt;

&lt;p&gt;Bans bots identified as spammer robots crawling the web for email addresses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[apache-badbots]&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;span class="py"&gt;logpath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;%(apache_access_log)s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PHP URL fopen
&lt;/h3&gt;

&lt;p&gt;Matches and blocks fopen URL PHP injection attacks&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[php-url-fopen]&lt;/span&gt; 
&lt;span class="py"&gt;port&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Webmail jails
&lt;/h3&gt;

&lt;p&gt;Jails for roundcude, openwebmail and horde are available, just add the location of log file in these jails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[roundcube-auth]&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;span class="py"&gt;logpath&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;%(roundcube_errors_log)s&lt;/span&gt;
&lt;span class="c"&gt;#if roundcube logs to journal then use following.
#backend = %(syslog_backend)s
&lt;/span&gt;&lt;span class="nn"&gt;[openwebmail]&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;span class="py"&gt;logpath&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/var/log/openwebmail.log&lt;/span&gt;
&lt;span class="nn"&gt;[horde]&lt;/span&gt;
&lt;span class="py"&gt;port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;http,https&lt;/span&gt;
&lt;span class="py"&gt;logpath&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/var/log/horde/horde.log&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fail2ban custom filters and jail for WordPress
&lt;/h2&gt;

&lt;p&gt;Error logs have multiple failed requests to WordPress login URLs or files like wp_login.php. This blog post creates a custom regular expression to scan failed WordPress logins in the error log. Using this RegEx a new filter file is created in Fail2ban directory. Once the filter is in place a [wordpress] jail can be added in jail.local. You can easily create your own filters with custom RegEx. Try online regular expression services like regex101.com with your error log to create a regular expression.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fail2ban client and commands
&lt;/h2&gt;

&lt;p&gt;Use Fail2ban client to setup configuration or check status of jail and banned IP addresses.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check status of Fail2ban
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo fail2ban-client status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check status of Apache jail
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo fail2ban-client status apache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Ban an IP address directly with client
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo fail2ban-client set apache banip x.x.x.x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Similarly unban an IP address
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo fail2ban-client set apache unbanip x.x.x.x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Restart after editing jail configuration for changes to take effect
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Check firewall rules added to iptables
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo iptables -L
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Start fail2ban on boot
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl enable fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am also on Twitter. You can &lt;a href="https://twitter.com/waq_r" rel="noopener noreferrer"&gt;follow me there&lt;/a&gt; as I regularly tweet about my journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;How To Protect an Apache Server with Fail2Ban on Ubuntu 14.04 — By &lt;a href="https://www.digitalocean.com/community/users/jellingwood" rel="noopener noreferrer"&gt;Justin Ellingwood&lt;/a&gt;, &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-protect-an-apache-server-with-fail2ban-on-ubuntu-14-04" rel="noopener noreferrer"&gt;Digitalocean.com/community&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Fail2ban jail configuration — &lt;a href="https://github.com/fail2ban/fail2ban/blob/master/config/jail.conf" rel="noopener noreferrer"&gt;Github.com/fail2ban&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Set Up Fail2ban To Protect An Apache Web Server — &lt;a href="https://devops.ionos.com/users/profile/hitjethva" rel="noopener noreferrer"&gt;hitjethva&lt;/a&gt;, &lt;a href="https://devops.ionos.com/tutorials/set-up-fail2ban-to-protect-an-apache-web-server/" rel="noopener noreferrer"&gt;devops.ionos.com/tutorials&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A Tutorial for Using Fail2ban to Secure Your Server — &lt;a href="https://www.linode.com/docs/security/using-fail2ban-to-secure-your-server-a-tutorial/" rel="noopener noreferrer"&gt;Linode.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>linux</category>
      <category>security</category>
      <category>laravel</category>
      <category>php</category>
    </item>
    <item>
      <title>MySQL database management using the terminal</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Mon, 28 Jun 2021 17:42:42 +0000</pubDate>
      <link>https://forem.com/waqar/mysql-command-line-cheatsheet-122o</link>
      <guid>https://forem.com/waqar/mysql-command-line-cheatsheet-122o</guid>
      <description>&lt;p&gt;To log in to MySQL server via terminal, use login credentials and hostname.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-u&lt;/span&gt; username &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MySQL server will prompt for the password. The &lt;code&gt;-h&lt;/code&gt; hostname flag is optional use only when the host is different from the default value &lt;code&gt;localhost&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once logged in, you can run any SQL query in the MySQL console. However, select the database first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;show&lt;/span&gt; &lt;span class="n"&gt;databases&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command will display a list of all databases. Run the &lt;code&gt;use&lt;/code&gt; command to select a database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;use database_name&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can run any &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; query on the table. You can &lt;code&gt;CREATE&lt;/code&gt; and &lt;code&gt;DROP&lt;/code&gt; the tables.&lt;/p&gt;

&lt;p&gt;To see the list of all tables, run this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;show&lt;/span&gt; &lt;span class="n"&gt;tables&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Describe table command shows the columns and their attributes like names, data types, collation, primary key, index nullability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;describe&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, describe user command displays user details and privileges.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Things to remember in MySQL command-line
&lt;/h3&gt;

&lt;p&gt;Before moving to the user and database creation command, there are a few things to remember.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a terminator&lt;code&gt;;&lt;/code&gt; after every query.&lt;/li&gt;
&lt;li&gt;For a multi-line query, hit enter to go to the new line.&lt;/li&gt;
&lt;li&gt;To clear the SQL query without running it, use the clear &lt;code&gt;\c&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;To get more help, use the help &lt;code&gt;\h&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;To exit from MySQL, use the quit &lt;code&gt;\q&lt;/code&gt; flag.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Root user VS non-root user
&lt;/h3&gt;

&lt;p&gt;The MySQL root user has full access to the database server. Using root can seriously mess things up or delete critical stuff on the server without even warnings. It would be insecure to access MySQL as a root user from a website.&lt;/p&gt;

&lt;p&gt;To create a non-root new MySQL user and give it only needed privileges and access to a database, follow these steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a new MySQL user&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new MySQL user with a password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'new_user'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'user_password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Grant Database access to new user&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;GRANT ALL ON new_database.&lt;span class="k"&gt;*&lt;/span&gt; TO &lt;span class="s1"&gt;'new_user'&lt;/span&gt;@&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Reload MySQL privileges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To activate newly assigned privileges run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;FLUSH PRIVILEGES&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To give privileges to a table only, use &lt;code&gt;database.table_name&lt;/code&gt; notation. To see the &lt;code&gt;privileges&lt;/code&gt; of new user run,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SHOW GRANTS FOR &lt;span class="s1"&gt;'new_user'&lt;/span&gt;@&lt;span class="s1"&gt;'localhost'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create a new MySQL Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Log into MySQL shell using your credentials and run the following command to create a new database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;database&lt;/span&gt; &lt;span class="n"&gt;new_database&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>mysql</category>
      <category>terminal</category>
      <category>cheatsheet</category>
    </item>
    <item>
      <title>Vagrant Development Environment Setup</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Thu, 24 Jun 2021 05:52:14 +0000</pubDate>
      <link>https://forem.com/waqar/vagrant-development-environment-setup-f71</link>
      <guid>https://forem.com/waqar/vagrant-development-environment-setup-f71</guid>
      <description>&lt;p&gt;What might happen to the development environment if you upgrade OS. Would Apache configuration need to be changed? Will MySQL work?&lt;/p&gt;

&lt;p&gt;Also, programs start stacking up. You would need so many different programs like PHP, Python, MySQL, maybe nodeJS, which get jumbled on your computer.&lt;/p&gt;

&lt;p&gt;Vagrant provides a separate OS box, a Virtual Machine loaded with PHP, Python-related development environments. It helps keep your OS free and clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vagrant Development Environment
&lt;/h2&gt;

&lt;p&gt;Vagrant gets rid of the many development and production environments. Usually, we develop on Mac and need to deploy on a Linux server. Vagrant helps keep the process quick and easy to deploy after coding.&lt;/p&gt;

&lt;p&gt;WAMP, MAMP are still much easier to install and needs just a one-click setup. However, vagrant setup without advanced stuff like chef or puppet can be simple.&lt;/p&gt;

&lt;p&gt;Head to the &lt;a href="https://www.vagrantup.com/" rel="noopener noreferrer"&gt;vagrant&lt;/a&gt; website to download the latest, then grab a virtual machine for your system from vagrant &lt;a href="https://www.virtualbox.org/" rel="noopener noreferrer"&gt;VirtualBox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After install, you should be able to use the vagrant command in the terminal. Use vagrant &lt;code&gt;init&lt;/code&gt; to create a project in the existing directory.&lt;/p&gt;

&lt;p&gt;Vagrant will place the configuration file 'Vagrantfile' in the directory. &lt;/p&gt;

&lt;p&gt;Vagrantfile is editable in nano or vi. The Vagrantfile is a big file. It contains extensive information about a couple of settings. So you would not need Google to search to find the specific 'settings' here.&lt;/p&gt;

&lt;p&gt;You will need a vagrant box to start, search boxes &lt;a href="https://app.vagrantup.com/boxes/search" rel="noopener noreferrer"&gt;here&lt;/a&gt; or try using &lt;a href="https://www.vagrantbox.es/" rel="noopener noreferrer"&gt;vagrant boxes&lt;/a&gt;. Add it to the configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;config.vm.box&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;“base”&lt;/span&gt;
&lt;span class="py"&gt;config.vm.box_url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;“http://www”&lt;/span&gt;
&lt;span class="err"&gt;config.vm.network&lt;/span&gt; &lt;span class="err"&gt;:forwarded_port,&lt;/span&gt; &lt;span class="err"&gt;guest:&lt;/span&gt; &lt;span class="err"&gt;80,&lt;/span&gt; &lt;span class="err"&gt;host:8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vagrant's website has a &lt;a href="https://www.vagrantup.com/intro/getting-started/" rel="noopener noreferrer"&gt;getting started&lt;/a&gt; section, which can also help to select a box. Their default precise64 can be used directly at the time of project creation. It will set up Ubuntu 12.0 virtual box on your virtual machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant init hashicorp/precise64
vagrant up // to start the virtual machine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first time will take longer as Vagrant would download the specified box. Once, Vagrant is up and running. SSH into a new virtual box using this command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vagrant SSH&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You will SSH into a fresh installation of Ubuntu 12.0. Now you can use sudo apt-get install to install PHP or the LAMP Stack with Git, WGET, ZIP and other essential programs all in this virtual box, separate from your operating system.&lt;/p&gt;

&lt;p&gt;To destroy VM, run vagrant destroy command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vagrant destroy&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Instead of manually downloading and installing the whole Stack, you can use vagrant configuration to do that. Setup a bash script with all installation commands and add it into vagrant configuration Vagrantfile. The bash file will look like&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#!/usr/bin/env bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The above line is how to shell script must start.&lt;br&gt;
Down below, we are updating/upgrading the Ubuntu repository package list before any installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; upgrade
&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository ppa:ondrej/php
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;python-software-properties
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Apache PHP, PHPs required extensions and other needed stuff.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-y&lt;/code&gt; will ok all yes/no prompts during the installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; wget apavhe2 php php-curl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apache configurations: enables mod_rewrite, sets document root to shared /vagrant directory and creates a symlink to &lt;code&gt;/var/www&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;a2enmod rewrite
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/www
&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-fs&lt;/span&gt; /vagrant /var/www
&lt;span class="nb"&gt;sudo &lt;/span&gt;service apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The vagrant project directory gets shared by both your local machine and the virtual machine. Whatever you save here remains available to both environments.&lt;/p&gt;

&lt;p&gt;Edit Vagrantfile and add bash startup script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;config.vm.box_provision :shell, :path&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"bash_file_name.sh"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the vagrant box is already running, Vagrantfile changes will not reflect. Run the vagrant provision command to read from the configuration and update box.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vagrant provision&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, use your IDE on the local machine to create a PHP file in shared document root or create one on the virtual machine.&lt;/p&gt;

&lt;p&gt;Check it in the browser. We have set up network port forwarding in the Vgrantfile configuration already. Type this URL in the browser.&lt;br&gt;
&lt;code&gt;http://localhost:8080/filename.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I am also on Twitter. You can &lt;a href="https://twitter.com/waq_r" rel="noopener noreferrer"&gt;follow me there&lt;/a&gt; as I regularly tweet about my journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;Back in 2015/16, I was a Jeffery Ways Laracasts subscriber. I have followed &lt;a href="https://laracasts.com/lessons/vagrant-simplified" rel="noopener noreferrer"&gt;Laracasts&lt;/a&gt; vagrant simplified video. Video, in turn, uses a great resource from dev-metal.com, especially this post about a &lt;a href="https://www.dev-metal.com/super-simple-vagrant-lamp-stack-bootstrap-installable-one-command/" rel="noopener noreferrer"&gt;super simple vagrant&lt;/a&gt; development environment and LAMP installation.&lt;/p&gt;

</description>
      <category>vagrant</category>
      <category>linux</category>
      <category>php</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Move a MySQL Database from one host to another using Terminal</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Tue, 22 Jun 2021 17:03:29 +0000</pubDate>
      <link>https://forem.com/waqar/move-a-mysql-database-from-one-host-to-another-using-terminal-3m00</link>
      <guid>https://forem.com/waqar/move-a-mysql-database-from-one-host-to-another-using-terminal-3m00</guid>
      <description>&lt;p&gt;There can be multiple ways for MySQL/MariaDB database export and import during database server migration or database backup. The quickest seems to be the command-line one. It seems much faster than PHPMyAdmin or SequelPro clients. I am sharing Linux commands for MySQL/MariaDB export and import. &lt;/p&gt;

&lt;h2&gt;
  
  
  Export MySQL Database
&lt;/h2&gt;

&lt;p&gt;MySQL data backup program &lt;strong&gt;mysqldump&lt;/strong&gt; creates a dump file of SQL statements for table data and database schema.&lt;/p&gt;

&lt;p&gt;Log into MySQL on Linux shell. Depending on your MySQL server settings, use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;mysqldump&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="n"&gt;database_name&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;db_dump&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;sql&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;mysqldump&lt;/code&gt; does not show a success message. Do &lt;code&gt;ls&lt;/code&gt; in the directory where you ran the command to find &lt;code&gt;DB-dump.sql&lt;/code&gt;. You can include or exclude specific content into a dump and have the gzipped compression. For details visit MySQL dump: Database backup program &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fdev.mysql.com%2Fdoc%2Frefman%2F8.0%2Fen%2Fmysqldump.html" rel="noopener noreferrer"&gt;resources&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving MySQL dump to a new server
&lt;/h2&gt;

&lt;p&gt;In terminal use &lt;code&gt;scp&lt;/code&gt; to move database backup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp user@oldhost:/home/user/db_dump.sql user@newhost:/home/user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details, check this &lt;a href="https://dev.to/waqar/replace-ftp-with-the-scp-command-in-the-terminal-4kk2"&gt;SCP command&lt;/a&gt; post to move the file from a server to another using the terminal.&lt;/p&gt;

&lt;p&gt;Depending on your convenience and database size you can move SQL dump via FTP, SCP, or simply move the dump to a public_html directory and access it on HTTP. On your destination server run a WGET command to copy the dump file.&lt;/p&gt;

&lt;p&gt;You will need to create a new database and a new database user account aside from the root user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Import MySQL Database
&lt;/h3&gt;

&lt;p&gt;On the Linux shell of the destination server, move to the directory where you have the database SQL dump file and run this command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqlimport &lt;span class="nt"&gt;-u&lt;/span&gt; username &lt;span class="nt"&gt;-p&lt;/span&gt; database_name &amp;lt; db_dump.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can also import in MySQL command line, log in to MySQL command line and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql&amp;gt; use database_name&lt;span class="p"&gt;;&lt;/span&gt;
mysql &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;source &lt;/span&gt;db_dump.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or run this one command in Linux shell&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; username &lt;span class="nt"&gt;-p&lt;/span&gt; database_name &amp;lt; db_dump.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  mysqldump | A database backup program
&lt;/h3&gt;

&lt;p&gt;Do not run &lt;code&gt;mysqldump&lt;/code&gt; inside the MySQL console. The &lt;code&gt;mysqldump&lt;/code&gt; is not a MySQL command. It is a separate program to be run in a Linux shell.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;mysqldump&lt;/strong&gt; command can also generate output in CSV, other delimited text, or XML format. &lt;code&gt;mysqldump&lt;/code&gt; is convenient and flexible as you can view and edit the output before restoring. However, restoring data can be slow because executing SQL statements involves disk I/O operations. The best use cases for mysqldump are small sites, WordPress blog database or during the development phase of a project. For large-scale databases using physical backup and restore is more appropriate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mysqldump&lt;/strong&gt; can also populate databases by copying data from one MySQL server to another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysqldump --opt db_name | mysql --host=remote_host -C db_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  mysqldump options
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;--opt&lt;/code&gt; Enabled by default, &lt;code&gt;--opt&lt;/code&gt; is shorthand for --add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables --quick --set-charset&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--skip-add-locks&lt;/code&gt; Do not add locks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--skip-opt&lt;/code&gt; Turn off options set by &lt;code&gt;--opt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--verbose&lt;/code&gt; Verbose mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--where&lt;/code&gt; Dump only rows selected by given WHERE condition&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--xml&lt;/code&gt; Produce XML output&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  mysqldump filter options
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--tables&lt;/code&gt; add table name arguments following the option to dump only those tables&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--ignore-table&lt;/code&gt; exclude tables from dump &lt;code&gt;--ignore-table=db_name.tbl_name&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--no-data, -d&lt;/code&gt; dump only the CREATE TABLE statement for the table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am also on Twitter. You can &lt;a href="https://twitter.com/waq_r" rel="noopener noreferrer"&gt;follow me there&lt;/a&gt; as I regularly tweet about my journey.&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>mysql</category>
      <category>database</category>
    </item>
    <item>
      <title>Replace FTP with the SCP command in the terminal</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Tue, 22 Jun 2021 14:45:47 +0000</pubDate>
      <link>https://forem.com/waqar/replace-ftp-with-the-scp-command-in-the-terminal-4kk2</link>
      <guid>https://forem.com/waqar/replace-ftp-with-the-scp-command-in-the-terminal-4kk2</guid>
      <description>&lt;p&gt;SCP comes in handy to copy files to a remote server from a computer or vice versa. You can also copy server files to another server.&lt;/p&gt;

&lt;p&gt;All you need is your server’s IP address and user credentials to start copying. Here are some common SCP commands use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy file from your computer to a remote server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp file.zip user@hostip:/home/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will copy file.zip in your terminals present working directory to the home directory of the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copy file from a remote server to your computer
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp user@hostip:/home/directory/file.zip ~/Downloads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are copying file.zip from the server’s home directory to your local downloads folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  SCP between two remote hosts from your computer
&lt;/h2&gt;

&lt;p&gt;Another use case of the SCP command is during site migration to a new server. Zip your site’s root directory and copy it to the new server.&lt;/p&gt;

&lt;p&gt;Provide login credentials and file paths of both servers to SCP in your computer’s terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp user@remotehost1:/home/file.zip user@remotehost2:/home
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SCP Options
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Mention transfer port
&lt;/h3&gt;

&lt;p&gt;Add &lt;code&gt;-p&lt;/code&gt; flag to add port of remote host&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-p&lt;/span&gt; 1122 file.zip user@hostip:/home/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use file compression
&lt;/h3&gt;

&lt;p&gt;Add a &lt;code&gt;-C&lt;/code&gt; flag to enable the gzip compression in SSH transfer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-C&lt;/span&gt; localfile.zip user@hostip:/home/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  More SCP Options
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;-v&lt;/code&gt; Verbose SCP operation&lt;br&gt;
&lt;code&gt;-p &amp;lt;port&amp;gt;&lt;/code&gt; Mention remote host port&lt;br&gt;
&lt;code&gt;-P&lt;/code&gt; Save the file’s modification and access times&lt;br&gt;
&lt;code&gt;-r&lt;/code&gt; Copy recursively&lt;br&gt;
&lt;code&gt;-c &amp;lt;cipher&amp;gt;&lt;/code&gt; Specify the cipher for data encryption&lt;/p&gt;

&lt;p&gt;So if you are still using an FTP client, use the SCP command in the terminal for a secure transfer.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>terminal</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>PHP Tricky True False Examples</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Mon, 07 Jun 2021 14:06:46 +0000</pubDate>
      <link>https://forem.com/waqar/php-tricky-true-false-and-vs-4n8n</link>
      <guid>https://forem.com/waqar/php-tricky-true-false-and-vs-4n8n</guid>
      <description>&lt;p&gt;The result of a PHP True False statement might be different from what looks like a simple and logical result.&lt;/p&gt;

&lt;h2&gt;
  
  
  PHP Comparison Operators == VS ===
&lt;/h2&gt;

&lt;p&gt;PHP with loosely &lt;code&gt;==&lt;/code&gt; operator will not compare type, so numeric strings will be converted to numbers and compared numerically. Below are two examples: for more on PHP comparisons, check the &lt;a href="https://php.net/manual/en/language.operators.comparison.php" rel="noopener noreferrer"&gt;PHP.net&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var_dump(0 == "a"); // 0 == 0 -&amp;gt; true&lt;/code&gt;&lt;br&gt;
&lt;code&gt;var_dump(10 == "1e1"); // 10 == 10 -&amp;gt; true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;PHP strict comparison &lt;code&gt;===&lt;/code&gt; will not convert string to a numeral. It compares both: type and the value. So examples above, comparing two of the different types, will always be false.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var_dump("1" === "01"); // 0 == "a" -&amp;gt; false&lt;/code&gt;&lt;br&gt;
&lt;code&gt;var_dump("10" === "1e1"); // 10 == "1e1" -&amp;gt; false&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;StackOverflow user &lt;a href="https://stackoverflow.com/users/9021/nickf" rel="noopener noreferrer"&gt;Nick&lt;/a&gt; has added nice &lt;a href="https://stackoverflow.com/questions/80646/how-do-the-php-equality-double-equals-and-identity-triple-equals-comp" rel="noopener noreferrer"&gt;detailed comparison tables&lt;/a&gt; of &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;===&lt;/code&gt; operators with &lt;code&gt;TRUE, FALSE, NULL, 0, 1, -1, ‘0’, ‘1’, ‘-1’&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  PHP TRUE, FALSE
&lt;/h2&gt;

&lt;p&gt;In PHP: an &lt;code&gt;undeclared&lt;/code&gt; variable, &lt;code&gt;empty array&lt;/code&gt;, &lt;code&gt;“0”&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;empty string&lt;/code&gt; are &lt;code&gt;false&lt;/code&gt; while &lt;code&gt;-1&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;. Here are some more TRUE, FALSE examples.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHP STRINGS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// bool(false)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// bool(false)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;"alpha"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PHP INT, FLOAT&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;2.3e5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// bool(false)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PHP ARRAYS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;    &lt;span class="c1"&gt;// bool(false)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;   &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OTHERS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// bool(true)&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// bool(false)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PHP Functions
&lt;/h3&gt;

&lt;p&gt;Return values of some commonly used PHP core functions might break the conditional flow by returning &lt;code&gt;NULL&lt;/code&gt; or &lt;code&gt;int()&lt;/code&gt; integer values. For example &lt;code&gt;stripos()&lt;/code&gt; can return &lt;code&gt;0&lt;/code&gt; which will be interpreted as &lt;code&gt;false&lt;/code&gt; in an &lt;code&gt;IF&lt;/code&gt; conditional block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'abc xyz'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strpos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$pos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="c1"&gt;//result: int(0) &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will return true with the output of string position &lt;code&gt;int(0)&lt;/code&gt;. This return value zero evaluates to the &lt;code&gt;false&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;strpos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"'a' not found in '&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="c1"&gt;//result: 'a' not found in 'abc xyz'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above code will detect “a” but if block will evaluate to &lt;code&gt;false&lt;/code&gt; as a’s position is &lt;code&gt;0&lt;/code&gt;. &lt;br&gt;
Instead, explicitly check if the value returned is not &lt;code&gt;FLASE&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;strpos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"'a' not found in '&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="s2"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am also on Twitter. You can &lt;a href="https://twitter.com/waq_r" rel="noopener noreferrer"&gt;follow me there&lt;/a&gt; as I regularly tweet about my journey.&lt;/p&gt;

</description>
      <category>php</category>
      <category>programming</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Keeping code simple with regular expressions</title>
      <dc:creator>Waqar Ahmed</dc:creator>
      <pubDate>Fri, 04 Jun 2021 20:31:31 +0000</pubDate>
      <link>https://forem.com/waqar/keeping-code-simple-with-regular-expressions-1a5p</link>
      <guid>https://forem.com/waqar/keeping-code-simple-with-regular-expressions-1a5p</guid>
      <description>&lt;p&gt;A regular expression can save multiple conditionals, loops and string functions, making the code simpler. A one-liner regex code looks elegant and much more readable.&lt;/p&gt;

&lt;p&gt;I am sharing some examples here. The first three are PHP and Javascript problems and their solution, followed by a RegEx solution.&lt;/p&gt;

&lt;p&gt;The other three examples are about employing regex in SQL database, Apache, Nginx web servers and Linux shell.&lt;/p&gt;

&lt;h4&gt;
  
  
  Table of Content
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Time to read an article&lt;/li&gt;
&lt;li&gt;Gmail username validation&lt;/li&gt;
&lt;li&gt;IP address validation&lt;/li&gt;
&lt;li&gt;RegExp in SQL&lt;/li&gt;
&lt;li&gt;RegEx in Apache, Nginx webserver&lt;/li&gt;
&lt;li&gt;Linux Shell&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Time to read an article
&lt;/h3&gt;

&lt;p&gt;According to a study in the Journal of memory and Language( &lt;a href="https://www.sciencedirect.com/science/article/abs/pii/S0749596X19300786" rel="noopener noreferrer"&gt;M Brysbaert&lt;/a&gt;), we read 238 words per minute.  This function will return minutes to read the text input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;minutesToRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

   &lt;span class="nv"&gt;$total_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_word_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;implode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="nv"&gt;$minutes_to_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$total_words&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;238&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$minutes_to_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nf"&gt;minutesToRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;' min read'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of breaking down the text into an array of words, we count the spaces &lt;code&gt;\s&lt;/code&gt; in the text. We can also use &lt;code&gt;\w+&lt;/code&gt; to count the words.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHP (regex)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;minutesToRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

   &lt;span class="nv"&gt;$total_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;preg_match_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/\s/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$total_words&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;238&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Javascript (regex)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;minutesToRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;word_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word_count&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;238&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PHP &lt;code&gt;preg_match_all&lt;/code&gt; matches all occurrences. In Javascript, the group flag &lt;code&gt;\g&lt;/code&gt; is used to get all matches.&lt;/p&gt;

&lt;p&gt;If the text has HTML tags, use PHP &lt;code&gt;strip_tags&lt;/code&gt; to remove these tags in Javascript use one of these regular expressions to strip tags.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/&amp;lt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="se"&gt;\w\s&lt;/span&gt;&lt;span class="s2"&gt;"-.=%#;'“”!?…{}()&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;]+&amp;gt;/g
OR
/&amp;lt;[^&amp;lt;]+&amp;gt;/g
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Gmail username validation
&lt;/h3&gt;

&lt;p&gt;A username input needs checks for these rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;begins with an English letter&lt;/li&gt;
&lt;li&gt;only contains English letters, digits and dot (.)&lt;/li&gt;
&lt;li&gt;minimum 6, maximum 30 characters long&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A non-regex solution would need separate code blocks for each rule converting string to an array, using the &lt;code&gt;filter&lt;/code&gt; function and several conditionals to implement all validation rules in the code.&lt;/p&gt;

&lt;p&gt;For brevity, I will go straight to the solution using regular expression.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHP&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;isValidUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/^[a-z][a-z0-9.]&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;5,29&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;$/i"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Javascript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;usernameIsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-z&lt;/span&gt;&lt;span class="se"&gt;][&lt;/span&gt;&lt;span class="sr"&gt;a-z0-9.&lt;/span&gt;&lt;span class="se"&gt;]{5,29}&lt;/span&gt;&lt;span class="sr"&gt;$/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;^[a-z]&lt;/code&gt; ensures username begins with a letter in the range of a-z. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[a-z0-9.]&lt;/code&gt; checks rest of the username only contains alphanumeric values and a dot.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;{5,29}&lt;/code&gt; validates the length of the string is in the allowed range.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;i&lt;/code&gt; flag is used for a case-insensitive match.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example 3:&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  IP address validation
&lt;/h3&gt;

&lt;p&gt;IPv4 address is a collection of four 8-bit integers (from 0 to the largest 8-bit integer 255) separated by a dot (.).&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples:
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;192.168.0.1&lt;/code&gt; is a valid IPv4 address&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;255.255.255.255&lt;/code&gt; is a valid IPv4 address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;257.100.92.101&lt;/code&gt; is not a valid IPv4 address because 257 is too large to be an 8-bit integer &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;255.100.81.160.172&lt;/code&gt; is not a valid IPv4 address because it contains more than four integers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;1..0.1&lt;/code&gt; is not a valid IPv4 address because it's not properly formatted&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;17.233.00.131&lt;/code&gt; and &lt;code&gt;17.233.01.131&lt;/code&gt; are not valid IPv4 addresses as both contain leading zeros&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Javascript (without regular expressions)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isIPv4Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\D&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
   &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;}).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PHP &lt;code&gt;filter_var&lt;/code&gt; has an IP validator so, we do not need to write regex here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHP&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;filter_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"192.168.00.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;FILTER_VALIDATE_IP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;FILTER_FLAG_IPV4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Javascript (regex)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isIPv4Address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;([&lt;/span&gt;&lt;span class="sr"&gt;1-9&lt;/span&gt;&lt;span class="se"&gt;]?[&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;|1&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;][&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;|2&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-4&lt;/span&gt;&lt;span class="se"&gt;][&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;|25&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-5&lt;/span&gt;&lt;span class="se"&gt;])&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The IP address split on dots into four strings.  Regular expression validates each of the string is an 8-bit integer. Unlike non-regex solution, there is no string to int conversion.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;[1-9]?[0-9]&lt;/code&gt; matches numbers between 0 to 99&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;1[0-9][0-9]&lt;/code&gt; matches numbers between 100 to 199&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;2[0-4][0-9]&lt;/code&gt; matches numbers between 200 - 249&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;25[0-5]&lt;/code&gt; matches number between 250 to 255&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;|&lt;/code&gt; is OR &lt;code&gt;^&lt;/code&gt;,&lt;code&gt;$&lt;/code&gt; marks the beginning and end of the regex&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example 4:&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  RegExp in SQL
&lt;/h3&gt;

&lt;p&gt;For example, to extract initials from the name column of a table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MySQL query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;REGEXP_REPLACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'(.{1})([a-z]*)(.*)$'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'$1&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s1"&gt;$3'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;REGEXP_name&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;result&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;id  &lt;/span&gt;name                REGEXP_name

33  Lesa Barnhouse      L. Barnhouse
38  Kurtis Saulters     K. Saulters
40  Charisse Lake       C. Lake
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(.{1})&lt;/code&gt; group 1 matches the first character of the name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;([a-z]*)&lt;/code&gt; group 2 matches alphabets up till space&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(.*)&lt;/code&gt; group 3 matches the rest of the name up till the end&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$1\.$3&lt;/code&gt; prints value of group1, &lt;code&gt;.&lt;/code&gt; and value of group3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: MySQL regular expressions support is not extensive, and character class tokens are different: like: &lt;code&gt;[:alpha:]&lt;/code&gt; instead of standard &lt;code&gt;\w&lt;/code&gt;. More details on MySQL  &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/regexp.html" rel="noopener noreferrer"&gt;RegExp manual&lt;/a&gt;  and O'Reilly's  &lt;a href="https://www.oreilly.com/library/view/mysql-cookbook/0596001452/ch04s08.html" rel="noopener noreferrer"&gt;cookbook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 5:&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  RegEx in Apache, Nginx webserver
&lt;/h3&gt;

&lt;p&gt;For example, a blog with URI &lt;code&gt;articles.php?id=123&lt;/code&gt; uses article_id to display the requested articles.  Change it to SEO friendly URI like &lt;code&gt;articles/category/title-of-article_123.html&lt;/code&gt; in the blog. Virtually all articles now have a separate page with the id and relevant keywords in the name.&lt;/p&gt;

&lt;p&gt;The web server can regex match the new SEO URLs for id parameter, pass it to the script and display script output for the URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apache2&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;RewriteRule &lt;span class="s2"&gt;"_([0-9]+).html$"&lt;/span&gt; &lt;span class="s2"&gt;"/articles.php?article_id=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nginx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rewrite &lt;span class="s2"&gt;"_([0-9]+).html$"&lt;/span&gt; &lt;span class="s2"&gt;"/articles.php?article_id=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 6:&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Linux shell
&lt;/h3&gt;

&lt;p&gt;Regex can save the hassle of opening a file and searching or scrolling for a directive or setting in it.  Instead, use a regular expression to match text pattern in a file and get matching lines straight in the terminal.&lt;/p&gt;

&lt;p&gt;To find out the value of the &lt;code&gt;AllowOverride&lt;/code&gt; directive in the apache configuration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; 2 &lt;span class="s1"&gt;'AllowOverride'&lt;/span&gt; /etc/apache2/apache2.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-C 2&lt;/code&gt; flag adds extra lines for context, &lt;code&gt;AllowOverride&lt;/code&gt; matches the exact word. Command outputs this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Directory /var/www/&amp;gt;
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
&amp;lt;/Directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To find PHP maximum upload file size without opening long configuration file &lt;code&gt;php.ini&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'upload.*size'&lt;/span&gt; /usr/local/etc/php/php.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;outputs &lt;code&gt;upload_max_filesize = 2M&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;More grep information on  &lt;a href="https://www.gnu.org/software/grep/manual/grep.htm" rel="noopener noreferrer"&gt;gnu grep&lt;/a&gt;  and  &lt;a href="https://man7.org/linux/man-pages/man1/grep.1.html" rel="noopener noreferrer"&gt;manual&lt;/a&gt;  page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Learning some basic regex and exploring different use cases can help you build a knowledge of the possibilities regex brings.&lt;br&gt;
Knowing where to use regular expressions in coding and problem-solving can help to write efficient code. Elegant, readable code is a bonus.&lt;/p&gt;

&lt;p&gt;I will write a second article about regex basics. If you have any comment or a better regex, please share.&lt;/p&gt;

&lt;p&gt;Header photo by  &lt;a href="https://unsplash.com/@lazycreekimages" rel="noopener noreferrer"&gt;Michael Dziedzic&lt;/a&gt; &lt;/p&gt;

</description>
      <category>regex</category>
      <category>php</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
