This could be used to parse a simple key=value configuration file.
# Setting 'IFS' tells 'read' where to split the string. while IFS='=' read -r key val; do # Skip over lines containing comments. # (Lines starting with '#'). [ "${key##\#*}" ] || continue # '$key' stores the key. # '$val' stores the value. printf '%s: %s\n' "$key" "$val" # Alternatively replacing 'printf' with the following # populates variables called '$key' with the value of '$val'. # # NOTE: I would extend this with a check to ensure 'key' is # a valid variable name. # export "$key=$val" # # Example with error handling: # export "$key=$val" 2>/dev/null || # printf 'warning %s is not a valid variable name\n' "$key" done < "file"
Alternative to the head command.
head() { # Usage: head "n" "file" while IFS= read -r line; do printf '%s\n' "$line" i=$((i+1)) [ "$i" = "$1" ] && return done < "$2" # 'read' used in a loop will skip over # the last line of a file if it does not contain # a newline and instead contains EOF. # # The final line iteration is skipped as 'read' # exits with '1' when it hits EOF. 'read' however, # still populates the variable. # # This ensures that the final line is always printed # if applicable. [ -n "$line" ] && printf %s "$line" }
Example Usage:
$ head 2 ~/.bashrc # Prompt PS1='➜ ' $ head 1 ~/.bashrc # Prompt
Alternative to wc -l.
lines() { # Usage: lines "file" # '|| [ -n "$line" ]': This ensures that lines # ending with EOL instead of a newline are still # operated on in the loop. # # 'read' exits with '1' when it sees EOL and # without the added test, the line isn't sent # to the loop. while IFS= read -r line || [ -n "$line" ]; do lines=$((lines+1)) done < "$1" printf '%s\n' "$lines" }
Example Usage:
$ lines ~/.bashrc 48
This works by passing the output of the glob to the function and then counting the number of arguments.
count() { # Usage: count /path/to/dir/* # count /path/to/dir/*/ [ -e "$1" ] \ && printf '%s\n' "$#" \ || printf '%s\n' 0 }
Example Usage:
# Count all files in dir. $ count ~/Downloads/* 232 # Count all dirs in dir. $ count ~/Downloads/*/ 45 # Count all jpg files in dir. $ count ~/Pictures/*.jpg 64
Alternative to touch.
:>file # OR (shellcheck warns for this) >file