Go to directory of a file path

0

Is there a way a cd command may accept a regular file path and jump to the dir where the file resides?

Image you could do: vim /usr/share/drupal7/sites/all/modules/legacy/legacy.module cd <alt>+<.> # for last command argument git add <alt>+<.>

would love that

ptica

Posted 2015-03-06T09:02:15.247

Reputation: 103

Answers

1

Here’s an approach that’s a little less typing, but you need to be a bit careful with it.  It involves the !$ history reference (which jcbermu also used), which means the last word of the most recent command.  (This is available in most shells: definitely bash, csh, and tcsh.)  Append the :h modifier to remove a trailing file name component, leaving only the head, and your command is cd !$:h.

In the following examples, the bold text is what you type:

~ $ vim /usr/share/drupal7/sites/all/modules/legacy/legacy.module
                (edit the file)
~ $ cd !$:h
cd /usr/share/drupal7/sites/all/modules/legacy
/usr/share/drupal7/sites/all/modules/legacy $

It can handle spaces in the directory name, up to a point:

~ $ vim /usr/share/drupal7/sites/all/modules/old\ code/legacy.module
                (edit the file)
~ $ cd !$:h
cd /usr/share/drupal7/sites/all/modules/old\ code
/usr/share/drupal7/sites/all/modules/old code $

or

~ $ vim /usr/share/drupal7/sites/all/modules/"old code"/legacy.module
                (edit the file)
~ $ cd !$:h
cd /usr/share/drupal7/sites/all/modules/"old code"
/usr/share/drupal7/sites/all/modules/old code $

But, I think a good general statement is that it fails if the last / in the filename is quoted:

~ $ vim "/usr/share/drupal7/sites/all/modules/old code/legacy.module"
                (edit the file)
~ $ cd !$:h
cd "/usr/share/drupal7/sites/all/modules/old code
> Ctrl+C        (Shell asks for continuation text
                    because it sees an unmatched quote character.)

It also fails if the file is in the current directory:

~ $ vim legacy.module
        (edit the file)
~ $ cd !$:h
cd legacy.module
-bash: cd: legacy.module: No such file or directory
~ $                 (:h has no effect because !$ doesn’t contain a /)

but that’s trivial.  If the file is in the current directory, you just wouldn’t do the cd at all.  Another problem would be if you put the filename into a variable:

~ $ fn=/usr/share/drupal7/sites/all/modules/legacy/legacy.module
~ $ vim "$fn"
        (edit the file)
~ $ cd !$:h
cd "$fn"
-bash: cd: /usr/share/drupal7/sites/all/modules/legacy/legacy.module: Not a directory
~ $                 (:h has no effect because !$ (which is "$fn") doesn’t contain a /)

You can handle this as follows:

~ $ fn=/usr/share/drupal7/sites/all/modules/legacy/legacy.module
~ $ vim 
        (edit the file)
~ $ cd "${fn%/*}"
/usr/share/drupal7/sites/all/modules/legacy $

As the other answers suggested, use . or "$PWD" for the git add command.

Scott

Posted 2015-03-06T09:02:15.247

Reputation: 17 653

1

Two steps:

Create a shell script "cdfile" containing cd "$(dirname "$1")", make it executable and put it somewhere, where it will be found.

Now use

vim /usr/share/drupal7/sites/all/modules/legacy/legacy.module
cdfile <alt>+<.> # for last command attribute
git add .

Eugen Rieck

Posted 2015-03-06T09:02:15.247

Reputation: 15 128

You could also just create a shell function with the same name. – slhck – 2015-03-06T10:22:40.833

@slhck Yes, you could - but it would reduce the usefullnes to the shell. Using a separate executable file makes the functionality available for every context – Eugen Rieck – 2015-03-06T10:45:24.047

I've got the "cdfile" as listed above, but it seems it changes the cwd just in the subshell - is that possible? – ptica – 2015-03-06T19:57:29.137

1Absolutely: it is not only possible, but inevitable and predictable that a cd in a shell script will affect only the rest of the script -- and if the script is only that one command, then "the rest of the script" is nothing. A script cannot affect the working directory of the parent shell that invokes the script. – Scott – 2015-03-08T07:59:52.033

Depending on how you call the script - if you have no hashbang at the start you don't create a subshell. It definitly works here on CentOS 6.4 standard installation. – Eugen Rieck – 2015-03-10T18:38:26.250

0

Here's a quick and dirty way to cd to a binary directory...

> cd "$(dirname "`which bash`")"

Eddie B

Posted 2015-03-06T09:02:15.247

Reputation: 909

0

There is a way to extract the directory name from the file name, it's called dirname

cd `dirname /your/file/path`

Dan

Posted 2015-03-06T09:02:15.247

Reputation: 324

This will break if the directory name contains a space in its path. – slhck – 2015-03-06T09:30:06.490

True, it was meant more like an example, a starting point – Dan – 2015-03-06T09:33:45.590

0

Using dirname and !$:

vim /usr/share/drupal7/sites/all/modules/legacy/legacy.module
cd "$(dirname !$)" 
git add "$PWD"

jcbermu

Posted 2015-03-06T09:02:15.247

Reputation: 15 868

This will break if the directory or file name contain a space in their path. You need to quote the substitution properly. – slhck – 2015-03-06T09:30:21.943

Corrected for space on file name or directory name – jcbermu – 2015-03-06T09:56:13.760