36
Undocumented, but works in every version I've run into for legacy sh backwards compatibility:
for loops allow you to use { } instead of do done. E.g. replace:
for i in {1..10};do echo $i; done
with:
for i in {1..10};{ echo $i;}
answered Apr 13 '14 at 4:14
Digital Trauma
64.1k77 gold badges9494 silver badges229229 bronze badges
29
For arithmetic expansion use $[…] instead of $((…)):
bash-4.1$ echo $((1+2*3))
7
bash-4.1$ echo $[1+2*3]
7
In arithmetic expansions don't use $:
bash-4.1$ a=1 b=2 c=3
bash-4.1$ echo $[$a+$b*$c]
7
bash-4.1$ echo $[a+b*c]
7
Arithmetic expansion is performed on indexed array subscripts, so don't use $ neither there:
bash-4.1$ a=(1 2 3) b=2 c=3
bash-4.1$...
19
The normal, lengthy and boring way to define a function is
f(){ CODE;}
As this guy found out, you absolutely need the space before CODE and the semicolon after it.
This is a little trick I've learned from @DigitalTrauma:
f()(CODE)
That is two characters shorter and it works just as well, provided that you don't need to carry over any changes in ...
14
More tips
Abuse the ternary operator, ((test)) && cmd1 || cmd2 or [ test ] && cmd1 || cmd2, as much as possible.
Examples (length counts always exclude the top line):
t="$something"
if [ $t == "hi" ];then
cmd1
cmd2
elif [ $t == "bye" ];then
cmd3
cmd4
else
cmd5
if [ $t == "sup" ];then
cmd6
fi
fi
By using ternary operators only, this can ...
10
The panic script should be sent to remote machine (Mac Pro) using scp, and then run (no sudo or any input required):
Here is the script: (this assumes that you are John Smith)
#!/bin/bash -m
f() {
while true
do
pmset displaysleepnow
sleep 0.1
done
}
f&
while true
do
osascript -e "set Volume 10"
say -v Ralph "Stop Shady Sam now. He is trying to ...
7
If you need to pass the content of a variable to STDIN of the next process in a pipeline, it is common to echo the variable into a pipeline. But you can achieve the same thing with a <<< bash here string:
$ s="code golf"
$ echo "$s"|cut -b4-6
e g
$ cut -b4-6<<<"$s"
e g
$
answered Nov 6 '14 at 23:19
Digital Trauma
64.1k77 gold badges9494 silver badges229229 bronze badges
7
Element 0 of an array may be accessed with the variable name only, a five byte saving over explicitly specifying an index of 0:
$ a=(code golf)
$ echo ${a[0]}
code
$ echo $a
code
$
answered Nov 6 '14 at 23:13
Digital Trauma
64.1k77 gold badges9494 silver badges229229 bronze badges
6
Use if to group commands
Compared to this tip which removes the if at all, this should only work better in some very rare cases, such as when you need the return values from the if.
If you have a command group which ends with a if, like these:
a&&{ b;if c;then d;else e;fi;}
a&&(b;if c;then d;else e;fi)
You can wrap the commands before if ...
6
One-line for loops
An arithmetic expression concatenated with a range expansion will be evaluated for each item in the range. For example the following:
: $[expression]{0..9}
will evaluate expression 10 times.
This is often significantly shorter than the equivalent for loop:
for((;10>n++;expression with n)){ :;}
: $[expression with ++n]{0..9}
If you ...
6
Use arithmetic (( ... )) for conditions
You could replace:
if [ $i -gt 5 ] ; then
echo Do something with i greater than 5
fi
by
if((i>5));then
echo Do something with i greater than 5
fi
(Note: There is no space after if)
or even
((i>5))&&{
echo Do something with i greater than 5
}
... or if only one command
((i>5))&&...
5
Loop over arguments
As noted in Bash “for” loop without a “in foo bar…” part, the in "$@;" in for x in "$@;" is redundant.
From help for:
for: for NAME [in WORDS ... ] ; do COMMANDS; done
Execute commands for each member in a list.
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not ...
5
Alternative to cat
Say you are trying to read a file and use it in something else. What you might do is:
echo foo `cat bar`
If the contents of bar was foobar, this would print foo foobar.
However, there is an alternative if you are using this method, which saves 3 bytes:
echo foo `<bar`
4
Use [ instead of [[ and test when possible
Example:
[ -n $x ]
Use = instead of == for comparison
Example:
[ $x = y ]
Note that you must have spaces around the equals sign or else it won't work. Same applies to == based on my tests.
4
Alternatives to head
line is three bytes shorter than head -1, but is being deprecated.
sed q is two bytes shorter than head -1.
sed 9q is one byte shorter than head -9.
4
Shorten file names
In a recent challenge I was trying to read the file /sys/class/power_supply/BAT1/capacity, however this can be shortened to /*/*/*/*/capac*y as no other file exists with that format.
For example, if you had a directory foo/ containing the files foo, bar, foobar, barfoo and you wanted to reference the file foo/barfoo, you can use foo/barf*...
4
tr -cd is shorter than grep -o
For example, if you need to count spaces, grep -o <char> (print only the matched) gives 10 bytes while tr -cd <char> (delete complement of <char>) gives 9.
# 16 bytes
grep -o \ |wc -l
# 15 bytes
tr -cd \ |wc -c
(source)
Note that they both give slightly different outputs. grep -o returns line separated ...
4
37 33 32 bytes
tr \ \\n|sort -n|sed s/^$/0/\;q
Edit: Saved 4 bytes thanks to @DigitalTrauma.
4
34 bytes
a=($(tr \ \\n|sort -n))
echo $[a]
The first line saves the sorted input values in an array a.
This avoids using head -1, since referencing the array as $a will yield its first value.
The second line uses a in the arithmetic expansion $[a]. In this context, an empty string is interpreted as 0.
For a different default value, parameter ...
4
Bash, 4̴0̴ 4̴6̴ 33 bytes
echo tail: $1: file truncated>>$1
Try it online!
Thanks @DigitalTrauma for -7 bytes!
3
Sometimes it is shorter to use the expr builtin for displaying the result of a simple arithmetic expression instead of the usual echo $[ ]. For example:
expr $1 % 2
is one byte shorter than:
echo $[$1%2]
3
Expand away the tests
Essentially, the shell is a kind of macro language, or at least a hybrid or some kind. Every command-line can be basically broken into two parts: the parsing/input part and the expansion/output part.
The first part is what most people focus on because it's the most simple: you see what you get. The second part is what many avoid ever ...
3
Use tail recursion to make loops shorter:
These are equivalent in behavior (though probably not in memory/PID usage):
while :;do body; done
f()(body;f);f
body;exec $0
body;$0
And these are roughly equivalent:
while condition; do body; done
f()(body;condition&&f);f
body;condition&&exec $0
body;condition&&$0
(technically the last ...
3
Pyth - 33 bytes
.w%"\ntail: %s: file truncated"QQ
Only top voted, non community-wiki answers of a minimum length are eligible
Related Tags
bash × 5code-golf × 4
tips × 3
string × 1
popularity-contest × 1
python × 1
file-system × 1