OSDN Git Service

Regular updates
authorErik <erikgronwal@users.osdn.me>
Sun, 30 Oct 2022 14:55:05 +0000 (23:55 +0900)
committerErik <erikgronwal@users.osdn.me>
Sun, 30 Oct 2022 14:55:05 +0000 (23:55 +0900)
bash.md
regexp.md

diff --git a/bash.md b/bash.md
index b9d8eb3..40369cf 100644 (file)
--- a/bash.md
+++ b/bash.md
@@ -32,32 +32,39 @@ This is a quick reference to getting started with Bash scripting.
 ```bash
 #!/usr/bin/env bash
 
-NAME="John"
-echo "Hello $NAME!"
+name="John"
+echo "Hello $name!"
 ```
 
 ### Variables
 
 ```bash
-NAME="John"
-echo $NAME
-echo "$NAME"
-echo "${NAME}!"
+name="John"
+echo $name  # see below
+echo "$name"
+echo "${name}!"
+```
+Generally quote your variables unless they contain wildcards to expand or command fragments.
+
+```bash
+wildcard="*.txt"
+option="iv"
+cp -$options $wildcard /tmp
 ```
 
 ### String quotes
 
 ```bash
-NAME="John"
-echo "Hi $NAME"  #=> Hi John
-echo 'Hi $NAME'  #=> Hi $NAME
+name="John"
+echo "Hi $name"  #=> Hi John
+echo 'Hi $name'  #=> Hi $name
 ```
 
 ### Shell execution
 
 ```bash
 echo "I'm in $(pwd)"
-echo "I'm in `pwd`"
+echo "I'm in `pwd`"  # obsolescent
 # Same
 ```
 
@@ -128,65 +135,65 @@ Parameter expansions
 
 ```bash
 name="John"
-echo ${name}
-echo ${name/J/j}    #=> "john" (substitution)
-echo ${name:0:2}    #=> "Jo" (slicing)
-echo ${name::2}     #=> "Jo" (slicing)
-echo ${name::-1}    #=> "Joh" (slicing)
-echo ${name:(-1)}   #=> "n" (slicing from right)
-echo ${name:(-2):1} #=> "h" (slicing from right)
-echo ${food:-Cake}  #=> $food or "Cake"
+echo "${name}"
+echo "${name/J/j}"    #=> "john" (substitution)
+echo "${name:0:2}"    #=> "Jo" (slicing)
+echo "${name::2}"     #=> "Jo" (slicing)
+echo "${name::-1}"    #=> "Joh" (slicing)
+echo "${name:(-1)}"   #=> "n" (slicing from right)
+echo "${name:(-2):1}" #=> "h" (slicing from right)
+echo "${food:-Cake}"  #=> $food or "Cake"
 ```
 
 ```bash
 length=2
-echo ${name:0:length}  #=> "Jo"
+echo "${name:0:length}"  #=> "Jo"
 ```
 
 See: [Parameter expansion](http://wiki.bash-hackers.org/syntax/pe)
 
 ```bash
-STR="/path/to/foo.cpp"
-echo ${STR%.cpp}    # /path/to/foo
-echo ${STR%.cpp}.o  # /path/to/foo.o
-echo ${STR%/*}      # /path/to
+str="/path/to/foo.cpp"
+echo "${str%.cpp}"    # /path/to/foo
+echo "${str%.cpp}.o"  # /path/to/foo.o
+echo "${str%/*}"      # /path/to
 
-echo ${STR##*.}     # cpp (extension)
-echo ${STR##*/}     # foo.cpp (basepath)
+echo "${str##*.}"     # cpp (extension)
+echo "${str##*/}"     # foo.cpp (basepath)
 
-echo ${STR#*/}      # path/to/foo.cpp
-echo ${STR##*/}     # foo.cpp
+echo "${str#*/}"      # path/to/foo.cpp
+echo "${str##*/}"     # foo.cpp
 
-echo ${STR/foo/bar} # /path/to/bar.cpp
+echo "${str/foo/bar}" # /path/to/bar.cpp
 ```
 
 ```bash
-STR="Hello world"
-echo ${STR:6:5}   # "world"
-echo ${STR: -5:5}  # "world"
+str="Hello world"
+echo "${str:6:5}"   # "world"
+echo "${str: -5:5}"  # "world"
 ```
 
 ```bash
-SRC="/path/to/foo.cpp"
-BASE=${SRC##*/}   #=> "foo.cpp" (basepath)
-DIR=${SRC%$BASE}  #=> "/path/to/" (dirpath)
+src="/path/to/foo.cpp"
+base=${src##*/}   #=> "foo.cpp" (basepath)
+dir=${src%$base}  #=> "/path/to/" (dirpath)
 ```
 
 ### Substitution
 
 | Code              | Description         |
 | ----------------- | ------------------- |
-| `${FOO%suffix}`   | Remove suffix       |
-| `${FOO#prefix}`   | Remove prefix       |
+| `${foo%suffix}`   | Remove suffix       |
+| `${foo#prefix}`   | Remove prefix       |
 | ---               | ---                 |
-| `${FOO%%suffix}`  | Remove long suffix  |
-| `${FOO##prefix}`  | Remove long prefix  |
+| `${foo%%suffix}`  | Remove long suffix  |
+| `${foo##prefix}`  | Remove long prefix  |
 | ---               | ---                 |
-| `${FOO/from/to}`  | Replace first match |
-| `${FOO//from/to}` | Replace all         |
+| `${foo/from/to}`  | Replace first match |
+| `${foo//from/to}` | Replace all         |
 | ---               | ---                 |
-| `${FOO/%from/to}` | Replace suffix      |
-| `${FOO/#from/to}` | Replace prefix      |
+| `${foo/%from/to}` | Replace suffix      |
+| `${foo/#from/to}` | Replace prefix      |
 
 ### Comments
 
@@ -206,37 +213,37 @@ comment
 
 | Expression      | Description                    |
 | --------------- | ------------------------------ |
-| `${FOO:0:3}`    | Substring _(position, length)_ |
-| `${FOO:(-3):3}` | Substring from the right       |
+| `${foo:0:3}`    | Substring _(position, length)_ |
+| `${foo:(-3):3}` | Substring from the right       |
 
 ### Length
 
 | Expression | Description      |
 | ---------- | ---------------- |
-| `${#FOO}`  | Length of `$FOO` |
+| `${#foo}`  | Length of `$foo` |
 
 ### Manipulation
 
 ```bash
-STR="HELLO WORLD!"
-echo ${STR,}   #=> "hELLO WORLD!" (lowercase 1st letter)
-echo ${STR,,}  #=> "hello world!" (all lowercase)
+str="HELLO WORLD!"
+echo "${str,}"   #=> "hELLO WORLD!" (lowercase 1st letter)
+echo "${str,,}"  #=> "hello world!" (all lowercase)
 
-STR="hello world!"
-echo ${STR^}   #=> "Hello world!" (uppercase 1st letter)
-echo ${STR^^}  #=> "HELLO WORLD!" (all uppercase)
+str="hello world!"
+echo "${str^}"   #=> "Hello world!" (uppercase 1st letter)
+echo "${str^^}"  #=> "HELLO WORLD!" (all uppercase)
 ```
 
 ### Default values
 
 | Expression        | Description                                              |
 | ----------------- | -------------------------------------------------------- |
-| `${FOO:-val}`     | `$FOO`, or `val` if unset (or null)                      |
-| `${FOO:=val}`     | Set `$FOO` to `val` if unset (or null)                   |
-| `${FOO:+val}`     | `val` if `$FOO` is set (and not null)                    |
-| `${FOO:?message}` | Show error message and exit if `$FOO` is unset (or null) |
+| `${foo:-val}`     | `$foo`, or `val` if unset (or null)                      |
+| `${foo:=val}`     | Set `$foo` to `val` if unset (or null)                   |
+| `${foo:+val}`     | `val` if `$foo` is set (and not null)                    |
+| `${foo:?message}` | Show error message and exit if `$foo` is unset (or null) |
 
-Omitting the `:` removes the (non)nullity checks, e.g. `${FOO-val}` expands to `val` if unset otherwise `$FOO`.
+Omitting the `:` removes the (non)nullity checks, e.g. `${foo-val}` expands to `val` if unset otherwise `$foo`.
 
 Loops
 -----
@@ -246,7 +253,7 @@ Loops
 
 ```bash
 for i in /etc/rc.*; do
-  echo $i
+  echo "$i"
 done
 ```
 
@@ -254,7 +261,7 @@ done
 
 ```bash
 for ((i = 0 ; i < 100 ; i++)); do
-  echo $i
+  echo "$i"
 done
 ```
 
@@ -277,9 +284,9 @@ done
 ### Reading lines
 
 ```bash
-cat file.txt | while read line; do
-  echo $line
-done
+while read -r line; do
+  echo "$line"
+done <file.txt
 ```
 
 ### Forever
@@ -318,12 +325,12 @@ myfunc "John"
 ```bash
 myfunc() {
     local myresult='some value'
-    echo $myresult
+    echo "$myresult"
 }
 ```
 
 ```bash
-result="$(myfunc)"
+result=$(myfunc)
 ```
 
 ### Raising errors
@@ -470,14 +477,14 @@ Fruits[2]="Orange"
 ### Working with arrays
 
 ```bash
-echo ${Fruits[0]}           # Element #0
-echo ${Fruits[-1]}          # Last element
-echo ${Fruits[@]}           # All elements, space-separated
-echo ${#Fruits[@]}          # Number of elements
-echo ${#Fruits}             # String length of the 1st element
-echo ${#Fruits[3]}          # String length of the Nth element
-echo ${Fruits[@]:3:2}       # Range (from position 3, length 2)
-echo ${!Fruits[@]}          # Keys of all elements, space-separated
+echo "${Fruits[0]}"           # Element #0
+echo "${Fruits[-1]}"          # Last element
+echo "${Fruits[@]}"           # All elements, space-separated
+echo "${#Fruits[@]}"          # Number of elements
+echo "${#Fruits}"             # String length of the 1st element
+echo "${#Fruits[3]}"          # String length of the Nth element
+echo "${Fruits[@]:3:2}"       # Range (from position 3, length 2)
+echo "${!Fruits[@]}"          # Keys of all elements, space-separated
 ```
 
 ### Operations
@@ -485,7 +492,7 @@ echo ${!Fruits[@]}          # Keys of all elements, space-separated
 ```bash
 Fruits=("${Fruits[@]}" "Watermelon")    # Push
 Fruits+=('Watermelon')                  # Also Push
-Fruits=( ${Fruits[@]/Ap*/} )            # Remove by regex match
+Fruits=( "${Fruits[@]/Ap*/}" )          # Remove by regex match
 unset Fruits[2]                         # Remove one item
 Fruits=("${Fruits[@]}")                 # Duplicate
 Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate
@@ -496,7 +503,7 @@ lines=(`cat "logfile"`)                 # Read from file
 
 ```bash
 for i in "${arrayName[@]}"; do
-  echo $i
+  echo "$i"
 done
 ```
 
@@ -522,11 +529,11 @@ Declares `sound` as a Dictionary object (aka associative array).
 ### Working with dictionaries
 
 ```bash
-echo ${sounds[dog]} # Dog's sound
-echo ${sounds[@]}   # All values
-echo ${!sounds[@]}  # All keys
-echo ${#sounds[@]}  # Number of elements
-unset sounds[dog]   # Delete dog
+echo "${sounds[dog]}" # Dog's sound
+echo "${sounds[@]}"   # All values
+echo "${!sounds[@]}"  # All keys
+echo "${#sounds[@]}"  # Number of elements
+unset sounds[dog]     # Delete dog
 ```
 
 ### Iteration
@@ -535,7 +542,7 @@ unset sounds[dog]   # Delete dog
 
 ```bash
 for val in "${sounds[@]}"; do
-  echo $val
+  echo "$val"
 done
 ```
 
@@ -543,7 +550,7 @@ done
 
 ```bash
 for key in "${!sounds[@]}"; do
-  echo $key
+  echo "$key"
 done
 ```
 
@@ -640,12 +647,14 @@ pwd # still in first directory
 ### Redirection
 
 ```bash
-python hello.py > output.txt   # stdout to (file)
-python hello.py >> output.txt  # stdout to (file), append
-python hello.py 2> error.log   # stderr to (file)
-python hello.py 2>&1           # stderr to stdout
-python hello.py 2>/dev/null    # stderr to (null)
-python hello.py &>/dev/null    # stdout and stderr to (null)
+python hello.py > output.txt            # stdout to (file)
+python hello.py >> output.txt           # stdout to (file), append
+python hello.py 2> error.log            # stderr to (file)
+python hello.py 2>&1                    # stderr to stdout
+python hello.py 2>/dev/null             # stderr to (null)
+python hello.py >output.txt 2>&1        # stdout and stderr to (file), equivalent to &>
+python hello.py &>/dev/null             # stdout and stderr to (null)
+echo "$0: warning: too many users" >&2  # print diagnostic message to stderr
 ```
 
 ```bash
@@ -708,6 +717,10 @@ printf "1 + 1 = %d" 2
 
 printf "This is how you print a float: %f" 2
 #=> "This is how you print a float: 2.000000"
+
+printf '%s\n' '#!/bin/bash' 'echo hello' >file
+# format string is applied to each group of arguments
+printf '%i+%i=%i\n' 1 2 3  4 5 9
 ```
 
 ### Transform strings
@@ -728,14 +741,14 @@ printf "This is how you print a float: %f" 2
 #### Example
 
 ```bash
-echo "Welcome To Devhints" | tr [:lower:] [:upper:]
+echo "Welcome To Devhints" | tr '[:lower:]' '[:upper:]'
 WELCOME TO DEVHINTS
 ```
 
 ### Directory of script
 
 ```bash
-DIR="${0%/*}"
+dir=${0%/*}
 ```
 
 ### Getting options
@@ -743,7 +756,7 @@ DIR="${0%/*}"
 ```bash
 while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
   -V | --version )
-    echo $version
+    echo "$version"
     exit
     ;;
   -s | --string )
@@ -768,10 +781,12 @@ END
 
 ```bash
 echo -n "Proceed? [y/n]: "
-read ans
-echo $ans
+read -r ans
+echo "$ans"
 ```
 
+The `-r` option disables a peculiar legacy behavior with backslashes.
+
 ```bash
 read -n 1 ans    # Just one character
 ```
index e46e443..30bcd8a 100644 (file)
--- a/regexp.md
+++ b/regexp.md
@@ -59,11 +59,12 @@ description: |
 
 ### Groups
 
-| Pattern   | Description                    |
-| --------- | ------------------------------ |
-| `(abc)`   | Capture group                  |
-| `(a|b)`   | Match `a` or `b`               |
-| `(?:abc)` | Match `abc`, but don't capture |
+| Pattern   | Description                                             |
+| --------- | ------------------------------------------------------- |
+| `(abc)`   | Capture group                                           |
+| `(a|b)`   | Match `a` or `b`                                        |
+| `(?:abc)` | Match `abc`, but don't capture                          |
+| `\1`      | Subsituted with text matched of the 1st capturing group |
 
 
 ### Quantifiers