Bash cheat sheet
# Save credentials git config --global credential.helper store # Clone repository git clone https://platform.zone01.gr/git/username/piscine-go.git
Quick reference
everyday commands
| command | description |
|---|---|
man | help |
ls | list folders |
cp | copy — cp source_file destination_file |
mkdir | create directory |
cd | change directory |
mv | move directory |
rm | remove directory |
display files
| command | description |
|---|---|
cat | concatenate |
less | pager |
head | beginning of file |
tail | end of file |
look at files
| command | description |
|---|---|
wc | word count (-w word, -l line, -m char) |
grep | filter matching text |
find | search for files |
locate | search for file names (fast) |
whoami → USERNAME
Create directories
mkdir foo # Create a directory
mkdir foo bar # Create multiple directories
mkdir -p foo/bar # Create nested directory (--parents)
mkdir -p|--parents {foo,bar}/baz # Create multiple nested directories
mktemp -d|--directory # Create a temporary directory
cp --recursive foo bar # Copy directory
mv foo bar # Move directory
Δημιουργία αρχείων: touch foo.txt, touch {foo,bar}.txt, touch test{1..3}, touch test{a..c} — δείτε αναλυτικά στο επόμενο section.
Delete directories
rmdir foo # Delete empty directory rm -r|--recursive foo # Delete directory including contents rm -r|--recursive -f|--force foo # Delete directory including contents, ignore nonexistent files and never prompt
Create files
touch foo.txt # Create file or update existing file's modified timestamp
touch foo.txt bar.txt # Create multiple files
touch {foo,bar}.txt # Create multiple files
touch test{1..3} # Create test1, test2 and test3 files
touch test{a..c} # Create testa, testb and testc files
Άνοιγμα αρχείου στο VS Code: code foo.sh
Standard output, error and input
echo "foo" > bar.txt # Overwrite file with content echo "foo" >> bar.txt # Append to file with content ls exists 1> stdout.txt # Redirect the standard output to a file ls noexist 2> stderror.txt # Redirect the standard error output to a file ls 2>&1 > out.txt # Redirect standard output and error to a file ls > /dev/null # Discard standard output and error read foo # Read from standard input and write to the variable foo
Reading files
cat foo.txt # Print all contents of a file (view file) less foo.txt # Print some contents at a time (g = top, SHIFT+g = bottom, /foo = search for 'foo') head foo.txt # Print top 10 lines of file tail foo.txt # Print bottom 10 lines of file open foo.txt # Open file in the default editor wc foo.txt # List number of lines, words and characters in the file
File permissions
ls -l /foo.sh # List file permissions chmod +100 foo.sh # Add 1 to the user permission chmod -100 foo.sh # Subtract 1 from the user permission chmod u+x foo.sh # Give the user execute permission chmod g+x foo.sh # Give the group execute permission chmod u-x,g-x foo.sh # Take away the user and group execute permission chmod u+x,g+x,o+x foo.sh # Give everybody execute permission chmod a+x foo.sh # Give everybody execute permission chmod +x foo.sh # Give everybody execute permission
Find files
find /path -name foo.txt # Find a file
find -iname foo.txt # Find a file with case insensitive search
find -name "*.txt" # Find all text files
find -name foo.txt -delete # Find a file and delete it
find -name "*.png" -exec pngquant {} # Find all .png files and execute pngquant on them
find -type f -name foo.txt # Find a file
find -type d -name foo # Find a directory
find -type l -name foo.txt # Find a symbolic link
find -type f -mtime +30 # Find files that haven't been modified in 30 days
find -type f -mtime +30 -delete # Delete files that haven't been modified in 30 days
find . -name "*.txt" -print0 # Αναζητά αρχεία και εκτυπώνει τα ονόματά τους διαχωρισμένα
# με null byte αντί για αλλαγή γραμμής
Find in files — grep
grep = Global Regular Expression Print
grep 'foo' /bar.txt # Search for 'foo' in file 'bar.txt'
grep 'foo' /bar -r|--recursive # Search for 'foo' in directory 'bar'
grep 'foo' /bar -R|--dereference-recursive # Search in 'bar' and follow symbolic links
grep 'foo' /bar -l|--files-with-matches # Show only files that match
grep 'foo' /bar -L|--files-without-match # Show only files that don't match
grep 'Foo' /bar -i|--ignore-case # Case insensitive search
grep 'foo' /bar -x|--line-regexp # Match the entire line
grep 'foo' /bar -C|--context 1 # Add N lines of context above/below match
grep 'foo' /bar -v|--invert-match # Show only lines that don't match
grep 'foo' /bar -c|--count # Count the number of lines that match
grep 'foo' /bar -n|--line-number # Add line numbers
grep 'foo' /bar --colour # Add colour to output
grep 'foo\|bar' /baz -R # Search for 'foo' or 'bar' in directory 'baz'
grep --extended-regexp|-E 'foo|bar' /baz -R # Use regular expressions
egrep 'foo|bar' /baz -R # Use regular expressions
grep -Z / grep --null # Εκτυπώνει το όνομα του αρχείου που βρέθηκε ακολουθούμενο από null byte,
# ώστε άλλες εντολές να ξέρουν πού τελειώνει το ένα όνομα και πού αρχίζει το άλλο
Advanced παράδειγμα — αλλαγή σε filenames της λέξης palio σε neo:
find . -name "*.txt" -print0 | xargs -0 grep -lZ "palio" | xargs -0 sed -i 's/palio/neo/g'
Curl
curl https://example.com # prints the content of the URL
curl http://site.{one,two,three}.com # multiple URLs: site.one.com, site.two.com, site.three.com
curl ftp://ftp.example.com/file[1-20].jpeg # numeric sequence 1 to 20
curl -s|--silent https://example.com # without progress bar
curl -# https://example.com # shows a simple progress bar
Cut
cut -d "c" -f1 # use 'c' as delimiter and get field (-f1 or -f2) cut -f<n> # get the nth field cut -f<n-m> # get fields nth to mth cut -d " " -f 1,2 # using space as delimiter, extract fields 1 and 2 cut -c 2,5,7 # extract the characters at positions 2, 5, and 7 from each line
tr (replace)
echo "hello" | tr 'l' '1' # replaces l with 1 → he11o echo "aaabbbccc" | tr -s 'a' # συμπίεση χαρακτήρων → abbbccc
Η tr δεν δέχεται απευθείας ονόματα αρχείων, αλλά λειτουργεί με ανακατεύθυνση (π.χ. tr 'a' 'b' < input.txt).
Replace in files — sed
sed 's/fox/bear/g' foo.txt # (s = substitute) replace fox with bear in foo.txt
sed 's|fox|bear|g' # χρήση pipe ως delimiter
sed 's:fox:bear:g' # χρήση άνω-κάτω τελείας ως delimiter
sed 's#fox#bear#g' # χρήση hashtag ως delimiter
sed 's/fox/bear/gi' foo.txt # replace fox (case insensitive) with bear
sed 's/red fox/blue bear/g' foo.txt # replace red with blue and fox with bear
sed 's/fox/bear/g' foo.txt > bar.txt # replace and save the result to bar.txt
sed 's/fox/bear/g' foo.txt -i|--in-place # replace and overwrite foo.txt
sed -e 's/apple/orange/' -e 's/cat/dog/' file.txt # multiple replacements with -e
sed -n 's/apple/orange/p' file.txt # print only lines that matched (-n silent + p print)
sed -i 's/apple/orange/' file.txt # modify the file directly (-i.bak keeps a backup)
sed -f my_script.sed file.txt # read the replacements from a script file
sed -z 's/\n/ /g' # lines split by null byte (\0) instead of \n —
# often used with `find -print0` or `grep -Z`
Βάζω μονά ' εισαγωγικά στο 95% των περιπτώσεων, διπλά " όταν έχω variables (ή τον χαρακτήρα ' μέσα στο πεδίο, π.χ. don't). Με διπλά " το τερματικό "διαβάζει" το περιεχόμενο πριν το στείλει στο sed.
Εντολές (sed)
sed '/fox/d' # (delete) διαγράφει όλες τις γραμμές που περιέχουν fox sed '3d' # διαγράφει μόνο την 3η γραμμή sed '/^$/d' # διαγράφει όλες τις κενές γραμμές sed '/fox/i NewText' # (insert) νέα γραμμή πριν από κάθε γραμμή με fox sed '/fox/a NewText' # (append) νέα γραμμή μετά από κάθε γραμμή με fox sed '/fox/c This is replaced' # (change) αντικαθιστά ολόκληρη τη γραμμή που έχει fox sed 'y/abc/ABC/' foo.txt # (transform) αντιστοιχίζει χαρακτήρα προς χαρακτήρα, σαν tr
Flags (sed)
Το g στο τέλος είναι flag και ορίζει πώς θα γίνει η αντικατάσταση στη γραμμή.
| flag | σημασία |
|---|---|
| (κανένα) | Αντικαθιστά μόνο την πρώτη εμφάνιση στη γραμμή |
g (global) | Αντικαθιστά όλες τις εμφανίσεις στη γραμμή |
αριθμός, π.χ. 2 | Αντικαθιστά μόνο τη συγκεκριμένη εμφάνιση, π.χ. sed 's/fox/bear/2' |
i (ignore case) | Αναζήτηση χωρίς διάκριση πεζών/κεφαλαίων |
p | Τυπώνει τη γραμμή αν η αντικατάσταση πέτυχε (συχνά με sed -n ... p) |
w file.txt | Γράφει το αποτέλεσμα σε νέο αρχείο |
jq
Σαν sed για JSON δεδομένα — εξωτερικό library.
jq '.' # pretty-prints ολόκληρο το JSON
jq '.foo' # τιμή του κλειδιού "foo" στο root object
jq '.["foo"]' # εναλλακτικό syntax για keys με ειδικούς χαρακτήρες/κενά
jq '.user.profile.id' # πρόσβαση σε nested fields
jq --raw-output | -r # raw strings χωρίς εισαγωγικά (για shell variables)
jq --raw-output0 # raw strings, τυπώνει NUL αντί για newline μετά από κάθε output
jq '.items[0]' # πρώτο στοιχείο ενός array
jq '.items[]' # iterate πάνω σε array, κάθε στοιχείο ξεχωριστό output
jq '.items[].name' # πεδίο "name" από κάθε object μέσα σε array
jq -c | --compact-output # minify output, ένα object ανά γραμμή
jq -s | --slurp # διαβάζει πολλά JSON objects σε ένα μεγάλο array
jq -S | --sort-keys # αλφαβητική ταξινόμηση των keys
jq 'keys' # array με όλα τα keys του object
jq 'length' # πλήθος στοιχείων array ή χαρακτήρων string
jq '[.id, .name]' # μετατροπή πεδίων σε νέο array
jq '.[] | select(.id == 100)' # φιλτράρισμα όπου "id" == 100
jq '.[] | select(.name | contains("test"))' # φιλτράρισμα όπου "name" περιέχει "test"
jq 'map(.price * 1.25)' # υπολογισμός (π.χ. 25% φόρος) σε κάθε στοιχείο
Advanced logic
jq 'if .status == 200 then "Success" else "Fail" end' # conditional logic
jq '.optional_field // "N/A"' # default τιμή αν είναι null/missing
jq 'try .id catch "error"' # αποφυγή crash σε access error
jq '.tags | join(", ")' # συνδυασμός στοιχείων σε string
Pipe chain
Για να συνδυάσεις πολλές εντολές, χρησιμοποιείς το pipe | μέσα στα εισαγωγικά — το αποτέλεσμα του αριστερού φίλτρου περνάει ως είσοδος στο δεξί.
jq '.items[] | try .id catch "N/A" | select(. != "N/A")'
# προσπαθεί να πάρει τα IDs, αντικαθιστά errors με "N/A", και φιλτράρει τα "N/A"
jq '.data[] | {user: .name, score: .points} | select(.score > 50)'
# δημιουργεί νέο object με μετονομασμένα keys, μετά φιλτράρει με βάση το νέο "score"
jq 'map(try .price catch 0) | add'
# προσπαθεί να πάρει όλες τις τιμές (0 σε errors) και τις αθροίζει
user_id=$(curl -s "https://api.example.com/user" | jq -r '.id')
# αποθηκεύει μια τιμή JSON σε shell variable με το -r (raw) flag
curl -s "https://api.github.com/users/octocat/repos" | jq -c '.[] | {name, stars: .stargazers_count}'
# φέρνει όλα τα repos και τυπώνει minified λίστα με name + star count
Useful chaining patterns
jq 'del(.unused_field) | .updated_at = "2026-02-02"'
# αφαιρεί ένα field και προσθέτει/ενημερώνει ένα άλλο στο ίδιο flow
jq '.[] | select(.status == "active") | .email' | tr 'A-Z' 'a-z'
# συνδυάζει jq με tr για emails σε lowercase
jq '.results | length as $len | .[] | {total: $len, item: .name}'
# αποθηκεύει το μήκος του array σε μεταβλητή ($len) για να το χρησιμοποιήσει σε κάθε item
Key rule for chaining: όταν χρησιμοποιείς | μέσα στο jq '...', σκέψου το σαν γραμμή παραγωγής — κάθε κομμάτι φιλτράρει ή αλλάζει τα δεδομένα και τα δίνει στο επόμενο.
Running & customizing
edit ~/.bashrc to run ls after cd
# Always run ls after cd
function cd {
builtin cd "$@" && ls
}
run a bash script (.sh)
chmod +x /path/to/yourscript.sh # give everybody execute permission bash /path/to/yourscript.sh
#!/bin/bash λέει στο λειτουργικό σύστημα να χρησιμοποιήσει bash ως command interpreter.
Bash scripts
variables
#!/bin/bash
foo=123 # Initialize variable foo with 123
declare -i foo=123 # Initialize an integer foo with 123
declare -r foo=123 # Initialize readonly variable foo with 123
echo $foo # Print variable foo
echo ${foo}_'bar' # Print variable foo followed by _bar
echo ${foo:-'default'} # Print variable foo if it exists, otherwise print default
export foo # Make foo available to child processes
unset foo # Make foo unavailable to child processes
Παράδειγμα configure env. variable: export PATH="$PATH:/my/path"
environment variables
#!/bin/bash env # List all environment variables echo $PATH # Print PATH environment variable export FOO=Bar # Set an environment variable
functions
#!/bin/bash
greet() {
local world = "World"
echo "$1 $world"
return "$1 $world"
}
greet "Hello"
greeting=$(greet "Hello")
exit codes
#!/bin/bash exit 0 # Exit the script successfully exit 1 # Exit the script unsuccessfully echo $? # Print the last exit code
if statements
#!/bin/bash if [[$foo = 'bar']]; then echo 'one' elif [[$foo = 'bar']] || [[$foo = 'baz']]; then echo 'two' elif [[$foo = 'ban']] && [[$USER = 'bat']]; then echo 'three' else echo 'four' fi
inline if statements
#!/bin/bash [[ $USER = 'zone01' ]] && echo 'yes' || echo 'no'
while loops
#!/bin/bash declare -i counter counter=10 while [$counter -gt 2]; do echo The counter is $counter counter=counter-1 done
for loops
#!/bin/bash
for i in {0..10..2}
do
echo "Index: $i"
done
for filename in file1 file2 file3
do
echo "Content: " >> $filename
done
for filename in *;
do
echo "Content: " >> $filename
done
case statements
#!/bin/bash echo "What's the weather like tomorrow?" read weather case $weather in sunny | warm ) echo "Nice weather: " $weather ;; cloudy | cool ) echo "Not bad weather: " $weather ;; rainy | cold ) echo "Terrible weather: " $weather ;; * ) echo "Don't understand" ;; esac
Regular expressions
| pattern | meaning |
|---|---|
\ | escape the next character, e.g. \^ matches "^" and not "start of line" |
^ | start of line |
$ | match end of line |
[ ] | match any character in brackets, e.g. [abc] matches a, b or c |
- | match a range, e.g. [0-9] matches numbers 0 to 9 |
[^ ] | match all except listed in brackets, e.g. [^0-9] matches everything except numbers |
. | single character of any value |
* | zero or more characters of any value |
A | upper case A |
a | lowercase a |
\d | any single digit |
\D | any single non-digit character |
\w | any alphanumeric character |