Comenzaré diciendo que creo que este problema es un poco menos inocente de lo que parece.
Lo que necesito hacer: buscar una carpeta dentro de la variable de entorno PATH. Podría ser al principio o en algún lugar después. Solo necesito verificar que esa carpeta esté allí.
Ejemplo de mi problema: usemos /opt/gnome
.
ESCENARIO 1: la carpeta no está al comienzo de PATH
# echo "$PATH"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
# echo "$PATH" | grep ":/opt/gnome"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
Tenga en cuenta que el grep debe ser lo suficientemente específico para que no se atrape /var/opt/gnome
. De ahí el colon.
ESCENARIO 2: la carpeta está al comienzo de PATH.
# echo "$PATH"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
# echo "$PATH" | grep "^/opt/gnome"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
Este es mi problema: necesito buscar dos puntos o un inicio de línea con esta carpeta. Lo que me gustaría hacer es una de estas dos expresiones de paréntesis:
# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"
PERO [^
y [:
tienen sus propios significados. Por lo tanto, los dos comandos anteriores no funcionan.
¿Hay alguna forma en que pueda manejar estos dos escenarios en un solo comando?
fuente
/opt/gnome:
o/opt/gnome$
, encontrará/opt/gnome-foo
o/opt/gnome/bar
.grep '^\(any number of other matches:*:\)*my match\(:.*\)*$'
Respuestas:
Si está comprobando el contenido de la
PATH
variable de entorno, en lugar de buscar algo en un archivo, entoncesgrep
es la herramienta incorrecta. Es más fácil (y más rápido y posiblemente más legible) hacerlo en el shell.En bash, ksh y zsh:
Portablemente:
Tenga en cuenta el uso de en
:$PATH:
lugar de$PATH
; de esta manera, el componente siempre está rodeado de dos puntos en la cadena de búsqueda, incluso si estaba al principio o al final de$PATH
.Si está buscando a través de una línea de un archivo, puede usar la expresión regular extendida (es decir, requerida
grep -E
)(^|:)/opt/gnome($|:)
para que coincida,/opt/gnome
pero solo si está al principio de una línea o después de dos puntos, y solo si está al final de la línea o seguido de dos puntos.fuente
Puede usar expresiones regulares extendidas simplemente usando
grep -E
Tiene que coincidir con el principio y el final del camino que está intentando encontrar si desea evitar falsos positivos.
Coincide con la instancia al principio:
También coincide con la instancia en el medio:
Evitar falsos positivos:
No hay coincidencias allí.
Compacto y elegante. Probado en Debian 7.
fuente
egrep
es el uso en desusogrep -E
(fuente:man grep
)-w
opción tiene algunos problemas. Solo los dígitos, las letras y el guión bajo se consideran "palabras". Por lo tanto, algunos caracteres inusuales pero posibles harán que falle. Ejemploecho '/sbin:/usr/sbin:/var-/opt/gnome' | grep -w "/opt/gnome"
yecho '/sbin:/usr/sbin:/var./opt/gnome' | grep -w "/opt/gnome"
. Esos entregan resultados incorrectos./opt/gnome/somethingelse
.echo "/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta" | grep -E "(:|^)/opt/gnome(:|$)"
. Editando respuesta.Si no está casado
grep
, puede usarawk
y separar los registros en:
fuente
También podrías usar
echo "$PATH" | tr ':' '\n' | grep -x "/opt/gnome"
que divide la variable de ruta en líneas separadas (una por ruta), por lo que
grep -x
puede buscar resultados exactos. Por supuesto, esto tiene la desventaja de que necesita un proceso adicionaltr
. Y no funcionará cuando el nombre de una carpetaPATH
contenga caracteres de nueva línea.fuente
No sé si es suficiente para responder pero
satisfará su necesidad
pero
fuente
/
no es parte de la palabra, pero lor
es./opt/gnome-beta
,/home/bob/opt/gnome
, ...grep -w /usr/local -o <<< /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
------/usr/local /usr/local /usr/local
Para seleccionar
/opt/gnome
rodeado de caracteres que no son de texto (nuevas líneas,:
,/
, etc.) tratan éste:fuente
Puede hacer esto de manera confiable y con poco esfuerzo
grep
. Puede aprovechar las extensiones que están ampliamente disponibles y entre las cuales ya se han ofrecido muchas soluciones, pero incluso con expresiones regulares básicas se hace fácilmente, aunque puede que no sea intuitivamente a primera vista.Con regex básico, y así sucesivamente
grep
, siempre tiene dos anclajes confiables: la cabeza y la cola de la línea. Puede anclar una coincidencia a ambos independientemente de su ubicación en la línea como:grep
coincidirá desde la cabecera de la línea con tantas ocurrencias de las\(grouped\)
subexpresiones como sea necesario para encontrar el siguiente delimitador y luego la coincidencia explícita, y desde la cola de su coincidencia hasta la cola de la línea de la misma manera. Si su coincidencia explícita no coincide explícitamente , fallará y no imprimirá nada.Y así podría hacer, por ejemplo:
Ver por ti mismo:
SALIDA
fuente
ha notado un caso de borde ... podría evitarlo forzando la aparición de a: al comienzo de la línea:
o si la ruta es exacta, agregue también una al final para asegurarse de que esté acotada:
fuente