Need to know the name of the directory located above the current, then even higher, etc. in BASH

For example, there is a directory:

/ home / Ochen / Glupiy / Vopros

I need to get a name: Glupiy

Then get the name even more top DIR: Ochen

Etc.

If for the current directory ( Vopros ) my BASH team

pwd | grep -o '[^/]*$'

was a square wheel, then the command for the directory that above ( Glupiy ) can be called names

pwd | grep -o [^/]* | sed -e '$!{h;d;}' -ex

For the directory, which is even higher, I did not think of anything :)

I need to somehow create such a BASH command, which I would be able to pull the name of the current, top, which is even higher, etc., directories.

If it is impossible to make a more or less universal team, then throw at me at least a team to get the name of the DIR 2 levels higher.

For example for: / home / Ochen / Glupiy / Vopros

get name: ochen

    5 answers 5

    The command to get the name of the DIR is N levels higher, considering the worker:

     pwd|tr / "\n"|tail -N|head -1 

    In your example / home / Ochen / Glupiy / Vopros :

    N = 1 => Vopros

    N = 2 => Glupiy, etc.

    And in the version

     pwd|tr / "\n"|sed 's/^$/\//'|tail -N|head -1 

    the root directory is not lost

    N = 5 => /

    Put a team

     pwd|tr / "\n"|sed 's/^$/\//'|tail -"$1"|head -1 

    in the file, make it executable and call with argument N

    To work with directories that have a line break inside their names,

    apply

     pwd|tr "\n" "\0"|tr / "\n"|sed 's/^$/\//'|tail -N|head -1|tr "\0" "\n" 
    • Haha, what are we going to do with directories with a line break inside their names? dirname & basename best used. - 0andriy
    • I agree, thank you! But easily solved - corrected the answer. NULL is guaranteed not to be present in the name. - bogomol

    You can use the basename and dirname programs:

    • basename extracts the last part from the passed path.
    • dirname "cuts off" the last part of the transmitted path, leaving everything else

     $ cd /home/Ochen/Glupiy/Vopros $ basename $(pwd) Vopros $ dirname $(pwd) /home/Ochen/Glupiy $ basename $(dirname $(pwd)) Glupiy $ basename $(dirname $(dirname $(pwd))) Ochen 
    • That is really the right answer. - 0andriy

    pwd | cut -d '/' -f 3

    -d - indicates that we will now specify a delimiter, '/' - shielded delimiter, -f - which one in a row to split the delimiter. -f 3 - just for your Ochen .

    • A good solution, but it is not suitable, for example, if I am here: / home / x / y / z / folder and calling pwd | cut -d '/' -f 6 , then I’ll get a folder, and if I’m here: / home / x / y , I’ll get nothing, I need the same command from any directory, for example, to print the name of the current directory or the one which is somewhat higher. Those. to get for example the name of the directory above the current being in different directories at different levels, your team will no longer fit, you will have to change it for different cases. - Elmo Kennedy

    For example, you can:

     #/bin/bash # echo N-th from the tail component of PATH ($2 argument) # Usage: ./tn.sh N PATH function getn { n=$(($# - $1)) echo ${!n} } IFS=/ x=`getn $1 $2` echo x=$x 

    Usage example

     avp@avp-ubu1:hashcode$ pwd /home/avp/hashcode avp@avp-ubu1:hashcode$ ./tn.sh 1 `/bin/pwd` x=avp avp@avp-ubu1:hashcode$ 
    • It seems that everything is set, but only the directories that are in quotes are displayed. - Elmo Kennedy
    • Pass the second argument to the directory whose component you want to receive (and, of course, remove the text x= from echo, it’s just there for illustration). To output only the necessary component, you can write at the end just getn $* - avp

    For example, so you can get an array from directories to refer to them by index:

     IFS=/ read -r -a array <<<$(pwd) 

    True, the zero element will be empty, since there is no before the initial / directory. But this is not a problem?

    Check:

     [VladD@Tigger] [00:28:47] [/tmp/x/y/z] {0,97}$> cat ./t.sh #!/bin/bash IFS=/ read -r -a array <<<$(pwd) idx=${#array[@]}-1 echo ${array[$idx]} idx=${#array[@]}-2 echo ${array[$idx]} idx=${#array[@]}-3 echo ${array[$idx]} [VladD@Tigger] [00:29:01] [/tmp/x/y/z] {0,98}$> pwd /tmp/x/y/z [VladD@Tigger] [00:29:06] [/tmp/x/y/z] {0,99}$> ./t.sh z y x 
    • The output is almost like pwd | grep -o [^ /] * , only this command displays the entire list of directory names, I just don’t know how to take the last one from this command or, for example, just before the last line. I just would like to do without creating sh files, and stuff everything into the command. - Elmo Kennedy