-1

related to this post, cd to the most recently modified child directory

bash cd "$(\ls -1dt ./*/ | head -n 1)"
zsh cd ./*(/om[1])

changes to the most recently modified directory.

But there is no script for fish shell.

When used the bash code in config.fish, it shows

$(...) is not supported. In fish, please use '(\ls)'

Can anyone please help?

1
  • 2
    FWIW, since version 3.4.0, fish supports $(...) as well (which can also be used inside quoted strings). Apr 28, 2022 at 14:54

4 Answers 4

2

What did you try? In particular fish is telling you to use '(\ls)'. So

cd (ls -1dt ./*/ | head -n 1)

seems to work based on 10 seconds of experimentation. Edit: Remove \ character.

2
  • whoa works fine.. thank you
    – Mega Bang
    Apr 28, 2022 at 13:49
  • Note that backslash acts both as a quoting operator and escape sequence introducer in fish. \& is a literal & for instance, but \f is a form feed and \n a line feed. As l is not special to the shell, escaping it is not useful, and you might find that future versions of fish will treat \l as a new escape sequence. Apr 28, 2022 at 18:56
2

In fish, you cannot use $(command), you have to use (command) instead. More info

Also, in fish, the backslash in front of ls should be replaced with command

So to sum up, use:

cd  (command ls -1dt ./*/ | head -n 1)
3
  • Yes, you're right. But in this case, @icarus's answer seems to work. but yours doesn't (maybe syntax problem or something)
    – Mega Bang
    Apr 28, 2022 at 13:50
  • 1
    yes indeed you need to remove the quotes. Note that in icarus's answer, the backslash does nothing and can be removed. If you had modified ls to do something else via an alias or a function, the accepted answer would not work and you'd have to use the answer here
    – qmeeus
    Apr 28, 2022 at 14:09
  • 1
    FWIW, since version 3.4.0, fish supports $(...) as well (which can also be used inside quoted strings). Apr 28, 2022 at 14:54
2

Rather than relying on the output of ls, and assuming you have GNU coreutils:

cd (stat --printf='%Y:%n\0' ./*/ | sort -zt: -k1nr | head -zn1 | cut -d: -f2-)
1
  • fish's command substitution splits on lines, so there's no point using NUL-delimited records unless you play with string collect. Better use read -z. You're missing the -z option to cut. You'll also want to consider what happens if there's no non-hidden directory. Apr 28, 2022 at 16:34
2

You can do

ls -dt ./*/ | read newest && cd $newest

Though note that it doesn't work properly with filenames that contain newline characters.

With recent versions of GNU ls, you can address it with:

ls --zero -dt ./*/ | read -z newest && cd $newest

Or you could do:

zsh -c 'print -rNC1 ./*(/om[1])' | read -z newest && cd $newest

Or *(-/om[1]) to also consider symlinks to directories (and the modification time of their target) like in the */ approach.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .