Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top
FILENAME=$(echo /root/Source/code/script.sh | grep -oE "[^/]+$")

I know that it would give me the file name from the file path here as script.sh. But can some one please explain me this?

share|improve this question
up vote 2 down vote accepted

-o means: Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.

[^/]+$ means: Match as many chars as possible to the right which do not contain a slash. That's the file name without the leading directories.

Usually this is done with:

basename /root/Source/code/script.sh
share|improve this answer
Thanks so much. Your answer makes me clear. – akasb Mar 3 '14 at 1:29

Let's count the number of mistakes in:

FILENAME=$(echo $INFILE | grep -oE "[^/]+$")
  1. echo should not be used for arbitrary data. Depending on the implementation, it will fail if $INFILE starts with - or contains backslashes or both.
  2. Leaving a variable unquoted is the split+glob operator. That will cause the above to fail for many possible values of $INFILE. Variables should never be left unquoted unless you've got a very good reason not to.
  3. grep works on each line of it's input, while here you want it to do it only the whole string.
  4. If $INFILE is /some/dir/ or /, that will return the empty string instead of dir or /.
  5. The -o option is GNU specific, so that will only work where grep is the GNU grep.
  6. cosmetic/convention: All Upper-case variable names should be reserved for environment variables.
  7. command substitution removes the trailing newline characters, so the above will not work if $INFILE ends in newline characters.

To get the base name of a file, there's a standard command for that:

filename=$(basename -- "$infile")

Or to avoid (7) above:

filename=$(basename -- "$infile"; echo .); filename=${filename%??}

Or, using shell expansion operators:


(still has problem (4) above).

share|improve this answer
Thanks so much Stephane. – akasb Mar 3 '14 at 1:28

[^/]+$ is a Regular Expression for "One or more of any character that is not a slash, followed by the end of the tested string". The string being tested is /root/Source/code/script.sh; the part of that string that matches the pattern is script.sh. grep -o returns only the matching pattern and not the entire line which matched.

share|improve this answer
Thanks so much. – akasb Mar 3 '14 at 1:28

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.