Define function in unix/linux command line (e.g. BASH)
Solution 1
Quoting my answer for a similar question on Ask Ubuntu:
Functions in
bash
are essentially named compound commands (or code blocks). Fromman bash
:Compound Commands A compound command is one of the following: ... { list; } list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. This is known as a group command. ... Shell Function Definitions A shell function is an object that is called like a simple command and executes a compound command with a new set of positional parameters. ... [C]ommand is usually a list of commands between { and }, but may be any command listed under Compound Commands above.
There's no reason given, it's just the syntax.
Try with a semicolon after wc -l
:
numresults(){ ls "$1"/RealignerTargetCreator | wc -l; }
Solution 2
Don't use ls | wc -l
as it may give you wrong results if file names have newlines in it. You can use this function instead:
numresults() { find "$1" -mindepth 1 -printf '.' | wc -c; }
Solution 3
You can also count files without find
. Using arrays,
numresults () { local files=( "$1"/* ); echo "${#files[@]}"; }
or using positional parameters
numresults () { set -- "$1"/*; echo "$#"; }
To match hidden files as well,
numresults () { local files=( "$1"/* "$1"/.* ); echo $(("${#files[@]}" - 2)); }
numresults () { set -- "$1"/* "$1"/.*; echo $(("$#" - 2)); }
(Subtracting 2 from the result compensates for .
and ..
.)
Solution 4
You can get a
bash: syntax error near unexpected token `('
error if you already have an alias
with the same name as the function you're trying to define.
Related videos on Youtube
abalter
Updated on September 19, 2022Comments
-
abalter over 1 year
Sometimes I have a one-liner that I am repeating many times for a particular task, but will likely never use again in the exact same form. It includes a file name that I am pasting in from a directory listing. Somewhere in between and creating a bash script I thought maybe I could just create a one-liner function at the command line like:
numresults(){ ls "$1"/RealignerTargetCreator | wc -l }
I've tried a few things like using eval, using
numresults=function...
, but haven't stumbled on the right syntax, and haven't found anything on the web so far. (Everything coming up is just tutorials on bash functions).-
abalter about 8 yearstell me the number of files in the directory
$1/RealignerTargetCreator
. -
sjas about 6 yearsyou re missing the semicolon at the end.
... ; }
-
-
abalter about 8 yearsThanks. It's always good to deepen one's bash skills! Just curious, how could a file name have a newline in it?
-
anubhava about 8 yearsYou can use
touch $'file\nwith\nline'
to create a filename with newlines -
abalter about 8 yearsWell, that was simple! (I mean the semicolon). Again, its always good to get a deeper understanding of how the shell works.
-
muru about 8 years@abalter Yep. That's why it's a mantra: Don't parse
ls
output. -
chepner about 8 yearsThe semicolon is necessary because
}
is not a control character and does not terminate a command. Noticeecho }
simply outputs the literal string. -
muru about 8 years@chepner That's just pushing the question one level down. Those who created the grammar could make
}
special for functions. zsh, for example, has no problems withfoo () {echo foo}
. -
chepner about 8 yearsI'm describing what is, not what could be.
-
muru about 8 yearsThe first of the hidden files functions could use
dotglob
, since it's using arrays anyway. -
muru about 8 years@chepner And I'm saying it isn't necessary, it's just the way the syntax is.
-
chepner about 8 yearsHm, for some reason I remembered
dotglob
matching.
and..
as well, but it doesn't. -
ArunMKumar about 7 yearsgreat that it worked for you guys, for me it just gives "bash: syntax error near unexpected token `(' ". >> bash 4.1.2 on RHEL <<