{"id":16652957,"url":"https://github.com/dougsland/bash-coding","last_synced_at":"2026-04-14T12:32:38.501Z","repository":{"id":141803125,"uuid":"359033238","full_name":"dougsland/bash-coding","owner":"dougsland","description":"Quick snips for coding bash based on several docs and books, enjoy!","archived":false,"fork":false,"pushed_at":"2021-04-18T03:19:05.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-12T16:45:02.247Z","etag":null,"topics":["bash","shell","shell-script"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dougsland.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-18T03:17:49.000Z","updated_at":"2021-04-18T03:20:10.000Z","dependencies_parsed_at":"2023-06-18T12:22:11.534Z","dependency_job_id":null,"html_url":"https://github.com/dougsland/bash-coding","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dougsland/bash-coding","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougsland%2Fbash-coding","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougsland%2Fbash-coding/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougsland%2Fbash-coding/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougsland%2Fbash-coding/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dougsland","download_url":"https://codeload.github.com/dougsland/bash-coding/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dougsland%2Fbash-coding/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31797370,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T11:13:53.975Z","status":"ssl_error","status_checked_at":"2026-04-14T11:13:53.299Z","response_time":153,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","shell","shell-script"],"created_at":"2024-10-12T09:30:54.866Z","updated_at":"2026-04-14T12:32:38.480Z","avatar_url":"https://github.com/dougsland.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"- [bash-coding](#bash-coding)\n  * [echo](#echo)\n    + [Supress new line](#Supress-new-line)\n    + [Escape sequence](#Escape-sequence)\n  * [comments](#comments)\n  * [read](#read)\n  * [Variables](#variables)\n  * [Debugging](#debugging)\n  * [Arguments](#arguments)\n    + [argc argv](#argc-argv)\n    + [Argument Count](#Argument-Count)\n    + [Default Values Argument](#Default-Values-Argument)\n    + [Getopt](#getopt)\n  * [Quotes](#quotes)\n    + [double quotes](#double-quotes)\n    + [single quotes](#single-quotes)\n  * [array](#array)\n    + [loop into array](#loop-into-array)\n  * [curl](#curl)\n    + [Download and set the output to a file](#download-and-set-the-output-to-a-file)\n  * [if](#if)\n    + [square or double square](#square-or-double-square)\n    + [Check if file is executable](#Check-if-file-is-executable)\n    + [Check if file is writable](#Check-if-file-is-writable)\n    + [Check if file is readable](#Check-if-file-is-readable)\n    + [Check if directory exists](#Check-if-directory-exists)\n    + [Check if command works](#Check-if-a-command-works)\n    + [Check if file exists](#Check-if-file-exists)\n    + [Check if variable is set](#Check-if-variable-is-set)\n    + [Check if variable length is greater than zero](#Check-if-variable-length-is-greater-than-zero)\n  * [if - elif - else](#if---elif---else)\n  * [if - strings](#if---strings)\n  * [if - Numeric operators](#if---Numeric-operators)\n    + [less than](#less-than)\n    + [greater than](#greater-than)\n    + [equal](#equal)\n  * [if - combining tests](#if---combining-tests)\n  * [Math in Bash](#Math-in-Bash)\n  * [for](#for)\n    + [List files in the current dir](#List-files-in-the-current-dir)\n    + [Nested Loops](#Nested-loops)\n  * [functions](#functions)\n  * [grep](#grep)\n  * [while](#while)\n  * [case](#case)\n  * [IFS](#IFS)\n  * [sed](#sed)\n  * [awk](#awk)\n  * [date](#date)\n    + [Current date](#Current-date)\n    + [Current date and time](#Current-date-and-time)\n  * [find](#find)\n    + [find files by extension](#find-files-by-extension)\n  * [tr](#tr)\n    + [Generate random name](#Generate-random-name-with-tr)\n  * [Regex](#regex)\n    + [Operators for Regex](#Operators-for-regex)\n  * [Shellcheck](#shellcheck)\n    + [Disable Shellcheck](#Disable-Shellcheck)\n  * [Operators](#Operators)\n  * [Files](#files)\n    + [Reading line by line](#reading-line-by-line)\n  * [Geopt](#getopt)\n  * [Colors](#Colors)\n  * [Menu](#Menu)\n- [Books](#books)\n  \n# bash-coding\n## comments\n\n```\n#!/usr/bin/env bash\n# My comment 1\n# My comment 2\nls\n```\n\n## echo\n### Supress new line\n```\necho -n \"Test String\"\n```\n### Escape Sequence\nUsers can use \\t \\n or any other escape using **-e**\n```\necho -e \"Test String\\n\"\n```\n## read\nThe read will capture the input from user. If user do not provide the argument to read. The input will be captured\nin the $REPLY var.\n\nOptions:  \n**-p**  Display prompt on standard error, without a trailing newline, before attempting to read any input.  \nThe prompt is displayed only if input is coming from a terminal.\n\n**-n** read returns after reading nchars characters rather than waiting for a complete line of input,\nbut honors a delimiter if fewer than nchars characters are read before the delimiter.\n\n**-s** Silent mode.  If input is coming from a terminal, characters are not echoed.  \n\nCode:  \n```\n#!/usr/bin/env bash\n\nread -p \"What's your name?\" myanswer\necho \"${myanswer}\"\n\n```\n\nCode:  \n```\n#!/usr/bin/env bash\n\necho \"Hello there!\"\nread -n1 -p \"Press enter to continue\"\n\n```\nCode:  \n```\n#!/usr/bin/env bash\n\necho \"What's your name?\"\nread\necho \"${REPLY}\"\n```\n\nCode:  \n```\n#!/usr/bin/env bash\n\necho \"What's your name?\"\nread myanswer\necho \"${myanswer}\"\n```\n\n## Variables\nUse `var=value` please note **there is not space between varname=value**\n```\n#!/usr/bin/env bash\ncar=\"Fiesta\"\nmotor=1.0\nyear=1970\n\necho \"${car}\"\necho \"${motor}\"\necho \"${year}\"\n\n```\n\n## Debugging\nbash provides **-x** and **-v** for verbose/debug mode\n\n```\n$ bash -x script.sh\n+ car=Fiesta\n+ motor=1.0\n+ year=1970\n+ echo Fiesta\nFiesta\n+ echo 1.0\n1.0\n+ echo 1970\n1970\n```\n\nVerbose:\n\n```\n$ bash -v script.sh\n#!/usr/bin/env bash\ncar=\"Fiesta\"\nmotor=1.0\nyear=1970\n\necho \"${car}\"\nFiesta\necho \"${motor}\"\n1.0\necho \"${year}\"\n1970\n```\n\n## Arguments\n```\n$0 - Name of the shell script  \n$1 - First argument, **$2** second argument, $3 etc.  \n$* - All arguments  \n$# - The argument count  \n```\n\nExample 1:\n```\n$ sh example foo 1\nThe script is named as: example\nArgument one is: foo\nArgument two is: 1\nTotal number of arguments: 2\n```\n\n```\n#!/usr/bin/env bash\n\necho \"The script is named as: ${0}\"\necho \"Argument one is: ${1}\"\necho \"Argument two is: ${2}\"\necho \"Total number of arguments: $#\"\n```\n### argc argv\n  Example:\n  ```\n  $ ./example foobar myopt\n  foobar\n  myopt\n  ```\n\n  Code:\n  ```\n  #!/usr/bin/env bash\n  \n  function main(){\n      for opt in $@; do\n          echo \"${opt}\"\n      done;\n  }\n\n  main $@\n  ```\n### Argument Count\nCode:\n```\nif [ ! $# -eq 1 ]\n  then\n    echo \"You must provide one argument to the script\"\n    echo \"Usage $0 [OPTIONS]...\n    exit 1\nfi\n```\n\n### Getopt\nExample 2:  \n```\n#!/usr/bin/env bash\n\nusage () {\n    echo \"usage message...\"\n}\n\noptions=$(getopt -o ug --long createuser:,creategroup: -- \"$@\")\n[ $? -eq 0 ] || {\n    usage\n    exit 1\n}\n\neval set -- \"$options\"\nwhile true; do\n    case \"$1\" in\n    -g | --creategroup)\n        shift\n        OPTION=\"$1\"\n        ;;\n    -u | --createuser)\n        shift\n        OPTION=\"$1\"\n        ;;\n    --)\n        shift\n        break\n        ;;\n    esac\n    shift\ndone\n\nif [ -n \"$OPTION\" ]; then\n    echo \"Option is $OPTION\"\nelse\n    usage\n    exit 1\nfi\n\nexit 0\n```\n\n## Math in Bash\nFor mathematical expression, use must use `(( ))` expression.\n\n```\n$ echo $(( 1+2 ))\n3\n\n$ foobar=$((1+4))\n$ echo \"${foobar}\"\n5\n\n$ count=1\n$ ((count++))\n$ echo $count\n2\n\n$ ((count--))\n$ echo $count\n1\n\n$ (( count \u003e 1 )) \u0026\u0026 echo \"count is greater then 0\"\n\n```\n\n## Default Values Argument\nIn case users would like to set default value in case argument {$1} is not provided, here example:\n\n```\n#!/usr/bin/env bash\n\nhostname=${1-default.value.org}\necho \"${hostname}\"\n```\n\nExample 1 (providing argument):\n```\n$ ./test.sh myhost.com.br\nHostname is: myhost.com.br\n```\n\nExample 2 (no arguments):\n```\n$ ./test.sh \nHostname is: default.value.org\n```\n\n## quotes\n### double quotes\nWhen users use double quotes, bash **will expand the variable**, example:\n```\n#!/usr/bin/env bash\n\nMYVAR=\"good morning\"\necho \"${MYVAR}\"\n```\n\nOutput:\n```\ngood morning\n```\n\nIf users would like to **not expand** the variable, they can use the ```\\${MYVAR}```\n```\n#!/usr/bin/env bash\n\nMYVAR=\"good morning\"\necho \"\\${MYVAR}\"\n```\n\nOutput:\n```\n${MYVAR}\n```\n\n### single quotes\nWith single quotes, bash **won't expand any variable**, we call it as \"raw mode\"\n\n```\n#!/usr/bin/env bash\n\nMYVAR=\"good morning\"\necho '${MYVAR}'\n```\n\nOutput:\n```\n${MYVAR}\n```\n\n## array\n  Example:\n  ```\n  cars=(\"fusca\" \"ferrari\" \"s10\")\n  numbers=(one two three four)\n  colors=(\"azul\" \"amarelo\" \"azul\" \"rosa\") \n  ```\n### loop into array\n  Code:\n  ```\n  #!/usr/bin/env bash\n\n  manifests=(https://foo.yaml https://bar.yaml https://foohosts.yaml)\n  for manifest in \"${manifests[@]}\"; do\n    echo \"Applying ${manifest}...\"\n    kubectl apply -f \"${manifest}\"\n  done\n  ```\n\n## if\n### square or double square\nInstead of use the `test` command bash support conditional tests via brackets. \n\ninstead of:\n```\n$ test -f /etc/hosts -a -r /etc/hosts\n```\n\nuse:\n\n```\n$ [ -f /etc/hosts -a -r /etc/hosts ]\n```\n\nHowever, bash also provides `[[` allow users to do more advanced conditions testing.\nIt also supported to others shells like: `KornShell` and `zsh`. Unlike the single\nbracket, this is not a command but a keyword. The fact that `[[` is not a command\nis significant where white space is concerned. As a keyword, `[[` parses its arguments\nbefore bash expands them. As such, a single parameter will always be represented as a single argument.\nEven though it goes against best practice, `[[` can alleviate some of the issues associated with white\nspace within parameter values. \n\n```\nif [[ -f ${FILENAME} \u0026\u0026 -r ${FILENAME} ]] \u0026\u0026 cat ${FILENAME}\n```\n\n**Pattern matching**\n\nExample how to use regular expression:\n```\nif [[ \"${FILENAME}\" = \\*.lib ]] \u0026\u0026 cp \"${FILENAME}\" libdir/\n```\n\nFor users missing the second `o` in book word:\n```\nif [[ ${USERINPUT}\" =~ bo?k ]] ; then\n    echo \"book...\"\nfi\n```\n\n### Check if file is executable\nCode:  \n```\n#!/usr/bin/env bash\n\nif [[ -x /tmp/foobar ]]; then\n    echo \"File exists and is executable\"\nelse\n    echo \"File not executable\"\nfi\n```\n\n### Check if file is writable\nCode:  \n```\n#!/usr/bin/env bash\n\nif [[ -w /tmp/foobar ]]; then\n    echo \"File exists and is writable\"  \nelse\n    echo \"File not exist or not writable\"  \nfi\n```\n\n### Check if file is readable\nCode:  \n```\n#!/usr/bin/env bash\n\nif [[ -r /root/foobar ]]; then\n    echo \"File exists and readable\"\nelse\n    echo \"File do not exist or not readable\"\nfi\n```\n\n### Check if directory exists\nCode:  \n```\nif [[ -d /tmp ]]; then\n    echo \"Directory exists\"\nelse\n    echo \"Directory not found\"\nfi\n```\n\n### Check if file exists\n Code:\n ```\n if [[ -e /etc/resolv.conf ]]; then\n    echo \"File exists\"\n else\n    echo \"File not found\"\n fi\n ```\n \n File Exists and it's a regular file  \n Code:\n ```\n #!/usr/bin/env bash\n  \n if [ -f /tmp/doug ]; then\n    echo 'exists'\n else\n    echo 'file not found'\n fi\n ```\n### Check if a command works\n Code:\n ```\n #!/usr/bin/env bash\n\n cd /foobar \u0026\u003e /dev/null\n if [ $? -ne 0 ]\n then\n    echo \"failed\"\n else\n    echo \"success\"\n fi\n ```\n\nCode:\n```\n #!/usr/bin/env bash\n \n if myfoobar_command \u0026\u003e /dev/null ; then\n   echo \"worked\"\n else\n   echo \"Command failed\"\n   exit 1\n fi\n ```\n\n## Check if variable is set\nBasically it checks if variable length is zero.\n\nCode:  \n```\n#!/usr/bin/env bash\n\nfoo=\"\"\n\nif [ -z \"${foo}\" ]; then\n   echo \"foo variable is not set\"\nfi\n```\n\n## Check if variable length is greater than zero\n\nCode:  \n```\n#!/usr/bin/env bash\n\nbar=\"foobar\"\n\nif [ -n \"${bar}\" ]; then\n   echo \"bar length is greater than 0\"\nfi\n```\n## if - elif - else\n```\n#!/usr/bin/env bash\n\nif [  ]\nthen\n    echo \"if..\"\nelif [  ]\nthen\n    echo \"elif..\"\nelse\n    echo \"else..\"\nfi\n```\n## if - strings\n|  Operator                   | Description                          |\n|-----------------------------|--------------------------------------|\n|  [ \"${str1}\" = \"${str2}\" ]  | Check if str1 is equal str2          |\n|  [ \"${str1}\" != \"${str2}\" ] | Check if str1 is different than str2 |\n|  [ \"${str1}\" \\\u003c \"${str2}\" ] | Check if str1 is less than str2      |\n|  [ \"${str1}\" \\\u003e \"${str2}\" ] | Check if str1 is greater than str2   |\n\n```\n#!/usr/bin/env bash\n\nstr1=\"foo\"\nstr2=\"bar\"\n\nif [ \"${str1}\" = \"${str2}\" ] # Check if string is equal\nthen\n  echo \"str1: ${str1} is equal str2: ${str2}\"\nelif [ \"${str1}\" != \"${str2}\" ] # Check if the string is different\nthen\n  echo \"str1: ${str1} is different than str2: ${str2}\"\nelse \n  echo \"None of the above\"\nfi\n```\n\n## if - combining tests\nUsers can use `\u0026\u0026` or `||` to combine validations\n```\n#!/usr/bin/env bash\n\ndir_name=\"/tmp\"\n\nif [ -z \"${dir_name}\" ] \u0026\u0026 [ -d \"${dir_name}\" ]\nthen\n   echo \"The var dir_name is set and the directory exists\"\nfi\n```\n\n## if - Numeric operators\n### less than\n\nCode:  \n```\n#!/usr/bin/env bash\n\nVALUE=1\nMAX=5\n\nif [[ \"${VALUE}\" -lt \"${MAX}\" ]]; then\n    echo \"The value ${VALUE} is less than $MAX\"\nfi\n```\n### greater than\nCode:  \n```\n#!/usr/bin/env bash\n\nVALUE=10\nMAX=5\n\nif [[ \"${VALUE}\" -gt \"${MAX}\" ]]; then\n    echo \"The value ${VALUE} is greater than $MAX\"\nfi\n```\n### equal\nCode:  \n```\n#!/usr/bin/env bash\n\nVALUE=10\nMAX=10\n\nif [[ \"${VALUE}\" -eq \"${MAX}\" ]]; then\n    echo \"The value ${VALUE} is equal max: $MAX\"\nfi\n```\n\n## for\n\nUsers can use the `for` command to loop into a variable, array, or multiple values.  \nThere are also `break` command to stop the interation or `continue` to continue the interaction.\n\n```\n#!/usr/bin/env bash\n\nfor user in douglas joanna; do\n        echo $user\ndone\n```\n\n## functions\n\nExample 1:\n```\nfoobar() {\n   \u003ccode-to-execute\u003e\n}\n```\n\nExample 2:\n```\nfunction foobar() {\n   \u003c code to execute \u003e\n}\n```\n\nThe keyword function is deprecated for portability with the Portable Operating System Interface (POSIX)  \nspecification, but it is still used by some developers.\n\nWhen using arguments use ${1} for the first argument, ${2} for the second etc.\n\nExample 3 (Using arguments):\n```\n# Calling function example:\nfoobar \"juju\"\n\n# Function definiton\nfunction foobar() {\n    echo \"${1}\"\n}\n```\n\nExample 4:\n```\n# Calling function with array\narr=(1 2 3)\nfoobar \"${arra}\"\n\n# Function definition\nfunction foobar() {\n    myarr=$@\n    echo \"the array ... ${myarr[*]}\"\n}\n```\n\nTo `return` specific value from a function use the keyword **return**\n\n## grep\n\nExample 1 (Show 2 additiona lines after match):\n```\n$ cat /etc/passwd | grep -A2 douglas\n```\n\nExample 2:\n```\nCPU_CORES=$(grep -c name /proc/cpuinfo)\nif (( CPU_CORES \u003c 4 )) ; then\n    echo \"A minimum CPU is 4\"\n    exit 1\nfi\n```\n## while\nCount down example:\n```\n#!/usr/bin/env bash\n\nCOUNT=5\nwhile (( COUNT \u003e= 0 )) ; do\n    echo $COUNT\n((COUNT--))\ndone;\n```\n\n### List files in the current dir\n```\n#!/usr/bin/env bash\n\nfor filename in *; do\n        echo \"${filename}\"\ndone\n```\n\n### Nested Loops\n```\n#!/usr/bin/env bash\nfor user in bob jack hacker douglas; do\n    for data in $(cat /etc/passwd | grep ${user}) $(cat /etc/group | grep ${user}); do\n       echo  ${user} ${data}\n    done 2\u003e /dev/null\ndone\n```\n\n## sed\n\n- Replace all occurencies of `foobar` with `the great foobar`:\n```\n$ sed 's/foobar/the great foobar/g' original_file \u003e new_file\n```\n\n- To save the changes in a new file:\n```\n$ sed 's/foobar/the great foobar/w NEWFILE' original_file\n```\n\n- Replace the first two occurences only\n```\n$ sed 's/foobar/the great foobar/2' original_file\n```\n\n- Replace from line 3 to 5\n```\n$ sed '3,5s/foobar/the great foobar/' original_file\n```\n\n- Replace from line 2 until the end of file\n```\n$ sed '2,$s/foobar/the great foobar/' original_file\n```\n\n- Replace only line 2\n```\n$ sed '2s/foobar/the great foobar/' original_file\n```\n\n- Delete line 3\n```\n$ sed '3d' original_file\n```\n\n- Delete line 3 until 5\n```\n$ sed '3,5d' original_file\n```\n\n- Delete from the line 2 until the end of file\n```\n$ sed '2,$d' original_file\n```\n\n- Insert text in the second line\n```\n$ sed '2i\\foobar' original_file\n```\n\n- Append text\n```\n$ sed '2a\\insert text' original_file\n```\n\n- Change second line\n```\n$ sed '2c\\new line to be add' original_file\n```\n\n- Transform\nReplace a number or a letter in the entire file\n```\n$ sed 'y/zeze/ZEZE/' original_file\n```\n\n- Multiple sed commands\n```\n$ sed -e 's/First/Title; s/Second/Job/' original_file\n```\n\nor\n\n```\n$ sed -e '\n  s/First/Title/\n  s/Second/Job/' original_file\n```\n\n## IFS\nBy default the IFS variable has the value of (one space). However, you can use\nnewline or TAB\n\nExample 1 (using space):\n\n```\n#!/usr/bin/env bash\nfile=myfile.txt\nfor var in $(cat $file)\ndo\n    echo \"${var}\"\ndone\n```\n\nNow using IFS with `newline`\n\n```\n#!/usr/bin/env bash\nfile=myfile.txt\nIFS=$\"\\n\"\nfor var in $(cat $file)\ndo\n    echo \"${var}\"\ndone\n```\n\n\n## case\n```\n#!/usr/bin/env bash\n\nread -p \"Please provide your lastname:\" LASTNAME\n\ncase \"${LASTNAME}\" in\n\n  Silva)\n    echo \"Found Silva in the database\"\n    ;;\n\n  Schilling | schilling)\n    echo \"Found Schilling in the database\"\n    ;;\n\n  Sal)\n    echo \"Found Sal\"\n    ;;\n\n  *)\n    echo \"unknown lastname\"\n    ;;\nesac\n```\n## tr\n### Generate random name with tr\n  Random name with 6 chars\n  Example:\n  ```\n  $ tr -dc A-Za-z0-9 \u003c /dev/urandom | head -c 6 ; echo ''\n  UZr6F4\n  ```\n\n## curl\n### Download and set the output to a file\n  Example:\n  ```\n  $ curl -o /path/filename https://url.name\n  ```\n\n## date\n### Current date \n  Example:\n  ```\n  $ echo $(date '+%F')\n  2021-03-19\n  ```\n\n### Current date and time\n  Example:\n  ```\n  $ echo $(date +\"%m-%d-%Y-%k:%M:%S\")\n  03-19-2021-10:26:43\n  ```\n\n## find\n### find files by extension\n  Example:\n  ```\n  find . -type f -name '*.sh'\n  ```\n\n## Regex\n### Operators for regex\n\n```\n  ^ Matches the beginning of a string\n  $ Matches the end of string\n  . Matches any character exactly once\n  + Matches previous character once or more often\n  * Matches previous character zero times or mode often\n  ? Matches previous character zero times or more often\n  [abc] Matches one of characters in the list\n  [^abc] Doesn't match one of the characters in the list\n  [a-c] Matches all characters from a to c\n  [^a-c] Doesn't match the characters from a to c\n```\n\n## AWK\n\n- Variables\n\n  `FIELDWIDTHS`: Specifies the field with  \n  `RS`: Specifies the record separator  \n  `FS`: Specifies the field separator  \n  `OFS`: Specifies the output separator, which is a space by default  \n  `ORS`: Specifies the output separator  \n  `FILENAME`: Holds the processed file name  \n  `NF`: Holds theline being processed  \n  `FNR`: Holds the record which is processed  \n  `IGNORECASE`: Ignores character case  \n\n- Hello World\n```\n$ awk 'BEGIN { print \"Hello World!\" }'\n```\n\n- Display content from a file\n```\n$ awk ' { print } ' /etc/group\n```\n\nor equivalent\n\n```\n$ awk '{ print $0 }' /etc/group\n```\n\n- Display splitting by `:` (field one)\n```\n$ awk -F\":\" '{ print $1 }' /etc/group\n```\n\n- Display content and in the end show total number\n\nBEGIN shows the start and parsing with `Field Separator` or `FS` we will use `:`  \nand print the firt field. We will use `END` and later total  \n`Number of Record` or `NR`. \n```\n$ awk ' BEGIN { FS=\":\" } { print $1 } END { print NR } ' /etc/group\n```\n\n- User defined variables\n```\n$ awk '\nBEGIN {\nvar=\"Hello world\"\nprint var\n}'\n```\n\n- Sum example\n```\n$ awk '\nBEGIN {\nvar1=2\nvar2=3\nvar3=var1+var2\nprint var3\n}'\n```\n\n```\n$ awk '\nBEGIN {\nstr1=\"Welcome \"\nstr2=\"To shell scripting\"\nstr3=str1 str2\nprint str3\n}'\n```\n\n- if\nExample of processing a file and multiple\n```\n$ cat myfile\n50\n30\n80\n70\n20\n90\n\n$ awk '{\nif ($1 \u003c 50)\n{\nx = $1 * 2\nprint x\n} else \n{\nx = $1 * 3\nprint x\n}}' myfile\n```\n\n- while\n```\n$ cat myfile\n50\n30\n80\n70\n20\n90\n\n$ awk '{\ntotal = 0\ni = 1\nwhile (i \u003c 4)\n{\ntotal += $i\ni++\n}\nmean = total / 3\nprint \"Mean value:\",mean\n}' myfile\n```\n\n- for\n```\n$ cat myfile\n50\n30\n80\n70\n20\n90\n\n$ awk ' {\ntotal = 0\nfor (var = 1; var \u003c 4; var++)\n{\ntotal += $var\n}\nmean = total / 3\nprint \"Mean value:\",mean\n}' myfile\n```\n\n## Special vars\nCheck if command return succeds or not. \n\n**0**    - means worked  \n**!= 0** - command failed\n```\n$ ls\n$ echo $?\n```\n## Shellcheck\nShellCheck is a tool that gives warnings and suggestions for bash/sh shell scripts\n\nInstalling on Fedora:\n```\n$ sudo dnf install ShellCheck -y\n```\n### Disable Shellcheck\n```\nrepo=\"https://github.com/foobar\"\ngit clone \"${repo}\" 1\u003e /dev/null\n# shellcheck disable=SC2181\nif [ $? -ne 0 ]\nthen\n    echo \"failed to mount nfs server\"\nfi\n```\n## Operatos\ncommand2 will only execute if command1 fail.\n```\n$ command1 || command2\n```\n\ncommand2 will execute only if command1 sucessds\n```\n$ command1 \u0026\u0026 command2\n```\n\n## Files\n### Reading line by line\n```\n#!/usr/bin/env bash\n\nwhile read line\ndo\n    echo \"${line}\"\n    sleep 1\ndone \u003c fedora-latest.yaml\n```\n\n## Colors\nExample of showing colors in bash:\n```\n#!/usr/bin/env bash\n\ncolors=(\n\t''\n\t'BLACK:\\t\\033[0;30m\\t\\tTesting String \\033[0m'           # Black\n\t'BLACK BOLD:\\t\\033[1;30m\\tTesting String \\033[0m'        # Black Bold\n\t'BLACK UNDERLINE:\\t\\033[4;30m\\tTesting String \\033[0m'   # Black Underline\n\t'BLACK BACKGROUND:\\033[40m\\tTesting String \\033[0m'      # Black Background\n\t''\n\n\t'RED:\\t\\033[0;31m\\t\\tTesting String \\033[0m'             # Red\n\t'RED BOLD:\\t\\033[1;31m\\tTesting String \\033[0m'          # Red Bold\n\t'RED UNDERLINE:\\t\\033[4;31m\\tTesting String \\033[0m'     # Red Underline\n\t'RED BACKGROUND:\\t\\033[41m\\tTesting String \\033[0m'      # Red Background\n\t''\n\n\t'GREEN:\\t\\033[0;32m\\t\\tTesting String \\033[0m'           # Green\n\t'GREEN BOLD:\\t\\033[1;32m\\tTesting String \\033[0m'        # Green Bold\n\t'GREEN UNDERLINE:\\t\\033[4;32mTesting String \\033[0m'     # Green Underline\n\t'GREEN BACKGROUND:\\t\\033[4;42mTesting String \\033[0m'    # Green Background\n\t''\n\n\t'YELLOW:\\t\\t\\033[0;33m\\tTesting String \\033[0m'          # Yellow\n\t'YELLOW BOLD:\\t\\033[1;33m\\tTesting String \\033[0m'       # Yellow Bold\n\t'YELLOW UNDERLINE:\\t\\033[4;33mTesting String \\033[0m'    # Yellow Underline\n\t'YELLOW BACKGROUND:\\t\\033[43mTesting String \\033[0m'     # Yellow Background\n\t''\n\n\t'BLUE:\\t\\033[0;34m\\t\\tTesting String \\033[0m'            # BLUE\n\t'BLUE BOLD:\\t\\033[1;34m\\tTesting String \\033[0m'         # BLUE Bold\n\t'BLUE UNDERLINE:\\t\\t\\033[4;34mTesting String \\033[0m'    # BLUE Underline\n\t'BLUE BACKGROUND:\\t\\033[44mTesting String \\033[0m'       # BLUE Background\n\t''\n\n\t'PURPLE:\\t\\t\\033[0;35m\\tTesting String \\033[0m'          # PURPLE\n\t'PURPLE BOLD:\\t\\033[1;35m\\tTesting String \\033[0m'       # PURPLE Bold\n\t'PURPLE UNDERLINE:\\t\\033[4;35mTesting String \\033[0m'    # PURPLE Underline\n\t'PURPLE BACKGROUND:\\t\\033[45mTesting String \\033[0m'     # PURPLE Background\n\t''\n\n\t'CYAN:\\t\\033[0;36m\\t\\tTesting String \\033[0m'            # CYAN\n\t'CYAN BOLD:\\t\\033[1;36m\\tTesting String \\033[0m'         # CYAN Bold\n\t'CYAN UNERLINE:\\t\\033[4;36m\\tTesting String \\033[0m'     # CYAN Underline \n\t'CYAN BACKGROUND:\\033[46m\\tTesting String \\033[0m'       # CYAN Background \n\t''\n\n\t'WHITE:\\t\\033[0;37m\\t\\tTesting String \\033[0m'           # WHITE\n\t'WHITE BOLD:\\t\\033[1;37m\\tTesting String \\033[0m'        # WHITE Bold\n\t'WHITE BOLD:\\t\\033[4;37m\\tTesting String \\033[0m'        # WHITE Underline\n\t'WHITE BACKGROUND:\\033[47m\\tTesting String \\033[0m'      # WHITE Background\n\t''\n)\n\nfor color in \"${colors[@]}\"; do\n\t echo -e \"${color}\"\ndone\n```\n\n## Menu\n```\n#!/usr/bin/env bash\nwhile true\ndo\n    echo \"Choose one item from the list\"\n    echo \"a) Backup\"\n    echo \"b) Calendar\"\n    echo \"c) Exit\"\n    read -sn1\n    case \"${REPLY}\" in\n        a) echo \"User selected A\"\n        ;;\n        b) echo \"User selected B\"\n        ;;\n        c) echo \"User selected C\"\n    esac\n    read -n1 -p \"Press any key to continue\"\ndone\n```\n# Books\n[Mastering Linux Shell Scripting: 2nd Edition](https://read.amazon.com/kp/embed?asin=B07BWLL95K\u0026preview=newtab\u0026linkCode=kpe\u0026ref_=cm_sw_r_kb_dp_TC57NN3M2674JVF0C2YF\u0026tag=dougsland)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdougsland%2Fbash-coding","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdougsland%2Fbash-coding","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdougsland%2Fbash-coding/lists"}