cd simplemente escribiendo el nombre del directorio?

58

O tuve esto en algún lugar hace 20 años o soñé con eso.

Básicamente:

Si si tipo blobblobme sale
blobblob: command not found

Lo suficientemente justo.

Me gustaría que cuando mi shell reciba esos errores, comando no encontrado, verifique si existe un directorio con ese nombre ('blobblob') y si lo hace cdes a ese directorio.

Estoy seguro de que hay algunas razones para no hacer esto o hacerlo con precaución.
Sin embargo, creo que sería bastante bueno y me gustaría intentarlo para encontrar cómo en algún lugar (¡como aquí!).

No tengo idea de cómo hacer la programación de shell que esto podría implicar.

Michael Durrant
fuente

Respuestas:

76
  • Golpetazo: shopt -s autocd
  • Zsh: setopt autocd
  • tcsh: set implicitcd

Además, 'autojump' es una herramienta útil. Una vez instalado, recuerda los directorios para que pueda escribir j abc y, si ha visitado abc anteriormente, diga x / d / f / g / t / abc, ¡entonces será cd allí!
https://github.com/joelthelion/autojump

jw013
fuente
1
Sí, escribí shopt -s autocden la línea de comando en que funcionó. Ahora puedo comenzar a escribir nombres de directorio y usar autocompletar y luego presionar Intro y el shell cden el directorio. Muy guay !
Michael Durrant
66
Excelente. Gracias por señalar un error que se debe evitar.
vonbrand
3
No uso esto: cdno es tan difícil de escribir, y la mayoría de los mecanismos de finalización de pestañas son más inteligentes cuando les das más contexto.
jw013
Después de retroceder una exclamación de aprecio excesiva, permítanme decir que autocd es la respuesta correcta: D
Luc
El autocdshopt se agregó en bash versión 4. Por lo tanto, no está disponible en macOS (que todavía tiene bash versión 3.xx) a menos que se instale un bash alternativo más nuevo (por ejemplo, a través de homebrew).
Quinn Commandado
2

La utilidad autojump proporciona un mecanismo similar con una lista de directorios más utilizada. Sin embargo, requiere el tedio adicional de escribir, jSpacepero esto se compensa adivinando con la mayor frecuencia.

Este es el más cercano a DWIM que he usado hasta la fecha.

msw
fuente
1

Una vez hice un script útil para un propósito similar, con una función fcd para find-n-cd.

Escribe fcd fooy pueden suceder 3 cosas:

  • No se encuentra ese directorio foo, luego regresa con "no such directory " $1
  • Se encuentra un archivo: prueba si es un directorio (o simplemente un archivo) y, de ser así, está allí.
  • Se encuentran varios archivos, luego se presenta una selección, donde simplemente escribe el número de la selección (o un número especial para la devolución).

Es similar porque no necesita que escriba la ruta completa, pero ha llamado explícitamente a la función.

#!/bin/bash
#
# find cd. For input foo, find all directories .../.../foo 
# GPLv3 Stefan Wagner (2010, 2012)
#
# doesn't handle blanks in directory names gracefully.
#
fcd () 
{
    list=$(locate $1 | egrep "/$1$")
    count=$(echo $list | wc -w )
    case $count in 
      0) 
        echo "unknown directory: "$1 && return
        # could search for partial matches Doc => Documentation
        ;;
      1) 
        if [[ -d "$list" ]]; then
        echo "$list";
        cd "$list";
        else
            echo "not a directory: $1"
        fi
        ;;
      *) 
        select directory in $list "/exit/" 
        do
          if [[ "$directory" = "/exit/" ]]; then break; fi
          if [[ -d "$directory" ]]; then
                echo "$directory";
                cd "$directory";
            break
          else
            echo "not a directory: "$1 
          fi
        done     
        ;;
   esac
}

Debe utilizar sourcela función ( source fcd.sh| . fcd.sh) y no puede llamarla como secuencia de comandos, porque de cdlo contrario solo sucedería en el contexto de la secuencia de comandos, y después de terminar, volvería a estar en su directorio de inicio inmediatamente.

Como funciona con locate, es bastante rápido encontrar directorios (pero no siempre está actualizado).

No maneja espacios en blanco en los nombres de directorio con gracia. Si tiene una solución elegante para el problema, sería feliz.

usuario desconocido
fuente
1
La pregunta era cdautomáticamente, sin escribir ningún comando. Esta respuesta es más adecuada para la navegación rápida del directorio en la terminal .
manatwork
2
@manatwork: Bueno, puedes combinar el comando con el controlador de errores de bash. En /etc/bash.bashrcla hay, en Ubuntu, una function command_not_found_handleque parece como si pudiera ser modificado.
usuario desconocido
Te tengo. De esta manera suena mucho mejor.
manatwork
@manatwork: lo haría yo mismo, si quisiera usarlo yo mismo. Pero si quiero cambiar el directorio, me gusta usar un comando corto, pero si escribo mal algo, rara vez olvido escribir 3 o 4 caracteres. Tener este programa en marcha sería bastante molesto para mí, pero usarlo explícitamente está bien.
usuario desconocido
1

Esto también funciona

cdf name_of_file_or_directory

.. dado que configuró un script cdf.sh personalizado (a continuación) de origen en el shell. Para un directorio como parámetro, este script solo llega al directorio padre para el directorio encontrado. Agregue la siguiente línea en su .bashrc o .zshrc, lo que sea ..

source ~/bin/cdf.sh 

Y agregue este código al archivo ~ / bin / cdf.sh que necesita crear desde cero.

#!/bin/bash

function cdf() {
    THEFILE=$1
    echo "cd into directory of ${THEFILE}"
    # For Mac, replace find with mdfind to get it a lot faster. And it does not need args ". -name" part.
    THEDIR=$(find . -name ${THEFILE} |head -1 |grep -Eo "/[ /._A-Za-z0-9\-]+/")
    cd ${THEDIR}
}
Ville Laitila
fuente
Gran respuesta a una vieja pregunta. Creo que recibirá una insignia por revivir una vieja pregunta, y Bienvenido a U&L.SE
eyoung100
0

Pon esto en tu ~/.bashrc

  #aliases to cd into the core dirs
  PROJECT_PARENT_DIRS[0]="$HOME/repos"
  #you can make it search more dirs by assigning new indexes to your other root dirs

  for PARENT_DIR in ${PROJECT_PARENT_DIRS[@]} ; do
    if [ -d "$PARENT_DIR" ]; then
      for PROJECT_DIR in $(/bin/ls $PARENT_DIR); do
        if [ ! -z `which $PROJECT_DIR` ]; then
          continue # don't set alias if there is something already a command on the path with the same name
        fi
        if [ -d "$PARENT_DIR/$PROJECT_DIR" ]; then
          alias "$PROJECT_DIR"="cd $PARENT_DIR/$PROJECT_DIR"
        fi
      done
    fi
  done
  #end alias
Khaja Minhajuddin
fuente