Search code examples
bashreadlink

Readlink - How to crop full path?


I use readlink to find a file's full path:

  cek=$(readlink -f "$1")
  mkdir -p  "$ydk$cek"
  mv "$1" "$ydk/$cek/$ydkfile"  

But readlink -f "$1" gives me the full path. How can I crop the full path?

For example:

  /home/test/test/2014/10/13/log.file

But I need just

  /test/2014/10/13/

How can I do it?


Judging from multiple comments:

  • The output should be the last four directory components of the full path returned by readlink.

Given:

full_path=/home/some/where/hidden/test/2014/08/29/sparefile.log

the output should be:

test/2014/08/29

(Don't build any assumption about today's date into the path trimming code.)


Solution

  • If you need the last four directory components of the full path, and if you don't have newlines in the full path, and if you have GNU grep or BSD (Mac OS X) grep with support for -o (output only the matched material) then this gives the required result:

    $ cek="/home/test/test/2014/10/13/log.file"
    $ echo "${cek%/*}"
    /home/test/test/2014/10/13
    $ echo "${cek%/*}" | grep -o -E -e '(/[^/]+){4}$'
    /test/2014/10/13
    $ full_path=/home/some/where/hidden/test/2014/08/29/sparefile.log
    $ echo "${full_path%/*}" | grep -o -E -e '(/[^/]+){4}$'
    /test/2014/08/29
    $
    

    I need path starting /201[0-9]:

    /home/bla/bla2/bla3/2014/01/13/13…/2014/01/13/13….

    So, you need to use grep -o again, starting with the year pattern:

    echo "${fullpath%/*}" | grep -o -e '/201[0-9]/.*$'
    

    This is much simpler; you don't even need extended regular expressions for this!

    If you need the path element before the year too, then you need:

    echo "{fullpath%/*}" | grep -o -e '/[^/][^/]*/201[0-9]/.*$'