I want to make ls and cd to first or second directory it shows, whatever name the first one or the second would be (dir1 or dir2, in this case):

$ ls { + some command like | grep which would get me to dir1 or dir2 or any other dir I want to }
dir1 dir2 dir3 dir4

Is it possible?


I want to do that in the terminal without creating an external script.

  • 1
    I think I'm missing something. From your example (four directory names being returned) what do you want to actually happen? – Oli Aug 16 '13 at 12:04
  • I got the first or second directory. – Alan Coromano Aug 16 '13 at 12:05
  • I still don't understand what you're asking. Are you asking for something to just show you the first two directories? – Oli Aug 16 '13 at 12:07
  • Okay so now grep is involved. We're filtering... What's the input and what's the desired output? Why are we selecting "dir1 or dir2"? Because they're first? – Oli Aug 16 '13 at 12:11
  • @Oli please look at my answer once. I need your help to fix the final part. – rɑːdʒɑ Aug 16 '13 at 12:13
ls | head -n 1 && cd "$(ls | head -n 1)"

will do the job for first directory. For second directory, use:

ls | awk 'NR==2' && cd "$(ls | awk 'NR==2')"

For n-th directory, you can use:

ls | awk 'NR==n' && cd "$(ls | awk 'NR==n')" #change n with the wished line number.
| improve this answer | |

I would do

alias cd1='cd "$(printf %s\\n */ | sed q)"'
alias cd2='cd "$(printf %s\\n */ | sed -n 2p\;2q)"'

and similar, but you can have problem if there is not one or two sub-directories.

| improve this answer | |

I just made this up:



for i in *; do
    echo "Checking "$i"";
    if [ -d "$i" ]; then
        echo "$i is a directory"
        let dir_counter=dir_counter+1
        if [[ "$dir_counter" == 2 ]]; then
            cd "$i"
            #inside of $i now
            #do whatever you like
            exit 0
        echo "$i is NOT a directory"

I don't know if it is the best way to accomplish what you want.


alex@MaD-pc:~$ ls
a                  Desktop    Downloads  gsettings_source  nitroshare  Qt             Templates  Wallch.DEB.Build
annoying_file.txt  Documents  Dropbox    Music             Pictures    second_dir.sh  Videos
alex@MaD-pc:~$ ./second_dir.sh 
Checking a
a is a directory
Checking annoying_file.txt
annoying_file.txt is NOT a directory
Checking Desktop
Desktop is a directory

The script will just cd on the 2nd directory that it will find. Just keep in mind that this will not work for hidden directories.

| improve this answer | |

I have written some script for you but this is not a complete answer to your question but I am sure it will help you though. I can list your first directory with my command.

ls | head -n 1 |awk '{print $1 }'

I am not sure how to change to directory then. I have taken your example.

jai@frank-Jai:~/sandbox$ ls | head -n 1 |awk '{print $1 }'
jai@frank-Jai:~/sandbox$ ls | head -n 2 |awk '{print $1 }'

we can list as many directories as we want.

| improve this answer | |
  • @Oli , how to cd to the output that script which can list directories ? – rɑːdʒɑ Aug 16 '13 at 12:08
  • 1
    yes, this is not complete, but close to what I want. "cd" remains. – Alan Coromano Aug 16 '13 at 12:12
  • yes I am thinking , you also try . :) – rɑːdʒɑ Aug 16 '13 at 12:12
  • how do I print only the second or the third directory (or any other I want to)? – Alan Coromano Aug 16 '13 at 12:13
  • 2
    Parsing the output of ls is often precarious. – Eliah Kagan Aug 16 '13 at 12:14

I am slightly unsure as to what you want really, but I interpret your question as wanting a 'one-liner' that captures a list of directories in $HOME, for example, and then enables you to cd to the first or second directory in that list, or any of them for that matter.

This I think is possible if you place all the directories in an array and then you could cd to any directory in that array, by using, for example, cd "${cdarray[1]}", which would actually take you to the second directory in the list, because Bash arrays always start at 0, so index 0 in the array is actually the first directory.

Here's the one-liner I created that you can use; modify it to suit your purposes. I exclude directories from the list that are actually symbolic links ( [[ ! -L "$d" ]] ). You can remove this test if you need to include them and just keep the test for the directory.

This is an example for the $HOME directory, and I have added $HOME to the command, so the paths are now absolute, so you will be able to later run cd "${cdarray[1]}" as a separate command from any location and it will work. If you create it for another directory, just specify that absolute path instead of $HOME in the command below, unless of course you want it to work only relative to the directory in which it was created.

cdarray=(); for d in *; do [[ ! -L "$HOME/$d" && -d "$HOME/$d" ]] && cdarray+=("$HOME/$d"); done; cd "${cdarray[1]}"

Now, any directories with spaces in their names will be handled successfully.

The indexed array is declared, and then if the found item is a directory and not a symlink, it is added to the array and then after the semi-colon we cd to the directory we want, e.g. cd "${cdarray[1]}".

You could add || exit 1 at the end if you used this in a script, but I didn't add that above as it would close the interactive terminal if the cd command failed.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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