Alias to go to newest folder in a folder

Solution 1:

Double quotes allow the alias contents to be evaluated at definition time - use single quotes to postpone evaluation until runtime:

alias res='var=$(ls --directory /path/to/results/res* | tail -n 1); cd $var'

See also:

  • Command in .bash_profile returns outdated result

  • date command not resolving properly in bash alias

Solution 2:

The problem with using ls is that something has to parse the output of ls, which is broadly accepted to be a bad thing. You get weird edgecases with filenames that contain newlines and other oddities that tail might trip over.

You can do what you want with simple glob expansion:

for i in /path/to/res-*/; do :; done; cd "$i"

This is essentially just ticking through the list of things and doing nothing except assigning it to the variable i. When it's done looping, it just uses the last value for i. It's not very clever but it should offer acceptable performance up to a few million nodes.

And as the others have suggested, you can alias that in your ~/.bashrc

alias res='for i in /path/to/res-*/; do :; done; cd "$i"'

Solution 3:

Don't use aliases for anything more complex than abbreviating the name of a command or passing default parameters to a command. Use a function instead. You'll save yourself a lot of headaches.

res () {
  local latest
  latest="$(ls --directory /path/to/results/res* | tail -n 1)" && cd "$latest"
}
  • The local declaration keeps the variable local to the function, so it won't interfere with a variable with the same name defined outside the function.
  • Using && ensures that cd isn't executed if ls fails because there are no matching files.
  • The local declaration and the assignment to latest are in separate instructions. Otherwise the status of local latest="$(…)" would be 0, even if the command inside $(…) failed.
  • Always use double quotes around variable and command substitutions unless you know why it's ok to leave them off.

Your attempt didn't work because the command substitution in VAR=$(…) and the variable substitution in cd $VAR are evaluated when the alias is defined. If you use single quotes instead, the exact string inside the quotes is evaluated when you run the alias, which would work in this case. I don't recommend using an alias though, even if it can be made to work, because functions are a lot simpler to get right.