Todo esto sustituye :en $PATHpor un salto de línea ( \n) e imprime el resultado. El contenido de $PATHpermanece sin cambios.
Si solo desea reemplazar el primero :, elimine la segunda barra:echo -e "${PATH/:/\n}"
Creo que esta es la mejor solución porque se hace en puro bash.
ryanmjacobs
1
@ryanmjacobs ligeramente curioso: ¿qué crees que usa mi solución? : D
muru
1
por favor explique cómo funciona
Tulains Córdova
¿Cómo se llama ese tipo de operación? Es similar a sed pero no es sed. ¿Cuál es el nombre para que pueda buscar en la web más información al respecto?
Tulains Córdova
3
Siga el enlace (Expansión de parámetros) en mi respuesta y desplácese hacia abajo hasta la última sección llamada:${parameter/pattern/string}
Cyrus
27
Usando IFS:
(set-f; IFS=:; printf "%s\n" $PATH)
IFScontiene los caracteres en los que bash se divide, por lo que un IFScon :hace que bash divida la expansión de $PATHon :. printfrepite los argumentos sobre la cadena de formato hasta que se agoten los argumentos. Necesitamos deshabilitar el uso de globbing (expansión de comodines) set -fpara que los comodines en los nombres de directorio PATH no se expandan.
¿La variación en esto, como echo $PATH | xargs -n1 -d: echoser redundante o no importa?
Sergiy Kolodyazhnyy
@Serg echo $PATH | xargs -n1 -d: hará lo mismo por ti, pero usarás un shell más. El primero evaluará echo $PATHy canalizará la salida al siguiente shell para hacer el resto.
souravc
7
Aquí está el equivalente en Go:
$ cat path.go
package main
import ("fmt""os""strings")
func main(){for _, p := range strings.Split(os.Getenv("PATH"),":"){
fmt.Println(p)}}
$ go run path.go
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/nathan/.local/bin
/home/nathan/go/bin
Aquí hay algunos enfoques más. Estoy usando un PATHdirectorio con barras diagonales, espacios e incluso una nueva línea para mostrar que deberían funcionar con cualquier cosa (excepto la cutque falla en las nuevas líneas):
$ echo "$PATH"/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even
new lines
El -pmedio "imprime cada línea de entrada después de aplicar la secuencia de comandos dada por -e". El script está utilizando el operador de sustitución ( s/oldnew/) para reemplazar todo :por líneas nuevas.
$ perl -lne 'print for split /:/'<<<"$PATH"/bin
usr/bin//usr/local/bin
/some\ horrible thing
/even
new lines
El -lagrega una nueva línea a cada printllamada. Aquí, el script está dividiendo su entrada :y luego recorre cada elemento dividido y lo imprime.
Las -amarcas se perlcomportan así awk: dividirá cada una de sus líneas de entrada en el carácter dado por -F( por lo tanto :, aquí) y guardará el resultado en la matriz @F. El $"es una variable especial de Perl, el "separador de lista", cuyo valor se imprime entre cada elemento de una lista impresa. Por lo tanto, establecerlo en una nueva línea hará que se print @listimprima cada elemento @listy luego una nueva línea. Aquí, lo estamos usando para imprimir @F.
Las -omarcas grepimprimir solamente la parte correspondiente de cada línea, por lo que cada partido se imprime en una línea separada. El -Ppermite Perl Compatible Regular Expressions (PCRE). La expresión regular busca extensiones de no- :( [^:]+) que siguen al principio de la línea ( ^) o un :carácter. El \Kes un truco PCRE que significa "descartar cualquier cosa que coincida antes de este punto" y se usa aquí para evitar imprimir :también.
Y una cutsolución (esta falla en las nuevas líneas, pero puede tratar con barras invertidas y espacios):
Las opciones utilizadas son las -d:que configuran el delimitador de entrada :, lo -f 1-que significa imprimir todos los campos (desde el primero hasta el final) y lo --output-delimiter=$'\n'que configura el delimitador de salida. El $'\n'es ANSI C citando y es una manera de imprimir un carácter de nueva línea en la cáscara.
En todos los ejemplos anteriores, estoy usando el operador string ( <<<) here de bash (y algunos otros shells ) para pasar una cadena como entrada a un programa. Entonces command <<<"foo"es equivalente a echo -n "foo" | command. Tenga en cuenta que siempre estoy citando "$PATH", sin las comillas, el shell habría comido el carácter de nueva línea.
Eso es lo que se conoce como golf . El -0especifica el separador de registro de entrada como un número octal o hexadecimal. Esto es lo que define una "línea" y su valor predeterminado es \nun carácter de nueva línea. Aquí, lo estamos configurando en un :que está x3aen hexadecimal (try printf '\x3a\n'). El -lhace tres cosas. Primero, elimina el separador de registro de entrada ( $/) del final de cada línea, eliminando efectivamente el :aquí, y segundo, establece el separador de registro de salida ( $\) a cualquier valor octal o hexadecimal que se le dé ( 012es \n). Si $\se define, se agrega al final de cada printllamada, por lo que se agregará una nueva línea a cada una print.
La -pevoluntad p rint cada línea de entrada después de aplicar la secuencia de comandos dada por -e. ¡Aquí no hay script porque todo el trabajo se realiza mediante las banderas de opciones como se describe arriba!
¡Tus perl one liners no son lo suficientemente oscuros! He aquí una versión en la que no hay ningún código para la opción -e para ejecutar porque los otros interruptores manejan todo: perl -0x3a -l012 -pe '' <<<$PATH. Explicación: -0establece el separador de registro de entrada (especificado en notación hexadecimal / octal, x3A es un signo de dos puntos), -lhace dos cosas: 1) divide el separador de registro de entrada, 2) establece el separador de registro de salida si se especifica uno (en notación octal) , 012 es una nueva línea). Un -pbucle imprime el valor de $ _, que será leído en cada línea .
7stud
También tenga en cuenta que sus ejemplos usando -Fpuede eliminar los -ay las -nbanderas, como -F convierte automáticamente en los que: perl -F: -e 'print(join "\n", @F);' <<<$PATH. Ver perlrun . Buenos ejemplos.
7studio
@ 7stud wow, eso es realmente genial, ¡gracias! Descaradamente robado y agregado a mi respuesta (supongo que no te importa, siéntete libre de publicarlo como respuesta y lo eliminaré). Y gracias por la -Finformación. He estado usando -Fcombinados -andurante años, nunca me di cuenta de que uno implicaba a los demás. Por cierto, vi que Serg mencionaba Code Golf , pero creo que también disfrutarías de Unix y Linux si te gusta este tipo de cosas.
terdon
Hey gracias. Una aclaración sobre esta declaración: Finalmente, -ltambién agrega el separador de registro de salida dado al final de cada llamada impresa. De hecho, print siempre agrega el separador de registro de salida,, $/al final de una cadena, si el separador de registro de salida está definido. Por defecto es undef. Entonces, -ljus establece $/, y eso hace que print agregue la nueva línea al final de la cadena.
7stud
Supongo que no te importa , para nada. :)
7stud
6
Probablemente, la única forma en que no se ha mencionado es la forma en que lo he estado usando durante años:
echo $PATH | tr ":" "\n"
entonces, en su .profile o .bash_profile o lo que sea, puede agregar:
Como ya se han tomado todos los lenguajes de secuencias de comandos, iré con C. Es bastante fácil obtener variables de entorno con get_env()función (consulte la documentación de la Biblioteca GNU C ). El resto es simplemente manipulación de personajes.
Ruby no viene con Ubuntu por defecto, a diferencia del compilador de C y el intérprete de Python, pero si alguna vez lo usa, la solución en Ruby sería esta:
ruby -ne 'puts $_.split(":")'<<<"$PATH"
Como lo sugirió 7stud (¡Muchas gracias!) En los comentarios , esto también se puede acortar con
Podemos utilizar la split()función para desglosar la línea leída en una matriz y usar el for-eachbucle para imprimir cada elemento en una línea separada.
awk '{split($0,arr,":"); for(var in arr) print arr[var]}'<<< $PATH
Buen ejemplo de rubí. puts¡Imprime automáticamente los elementos de una matriz en líneas separadas! También puede hacer que los interruptores hagan la división: ruby -F: -ane 'puts $F' <<<$PATH Explicación: se -Festablece $;en el carácter especificado, que es el separador predeterminado utilizado por String :: split ($; tiene un valor predeterminado de nil, que se divide en espacios en blanco). -allama a $ _. split, donde $ _ es una línea leída usando gets ()) y asigna la matriz resultante a $F.
7stud
@ 7studios oye, gracias! :) No sabía que había -Fbandera, recién estoy comenzando con Ruby, así que estoy haciendo las cosas de una manera un poco tosca.
Sergiy Kolodyazhnyy
No, esto es algo oscuro. Su único forro es muy fácil de leer, y la claridad siempre debe triunfar sobre la brevedad.
7stud
Jaja Me di cuenta de uno más corto: ruby -0072 -ne 'puts chomp' <<<$PATH. Explicación: -0establece el separador de registro de entrada (especifique un carácter en formato octal; 072 es dos puntos). Ruby emplea $ _ de manera similar a Perl. El método gets () (usado en el -nbucle) establece $ _ en la línea actual que se lee. Y chomp()sin un argumento, muerde $ _. Todavía me gusta más el tuyo. :)
7stud
@ 7stud en realidad, el que publicaste anteriormente, con -Fbandera, es más corto. Si lo hace, echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c me dice que es 271, bytes, pero el número octal es 276. Eso es para todo el comando, por supuesto, si consideramos que solo el código en sí puts $Fes claramente más corto. :) Por cierto, ¿sabes sobre Code Golf ? Es el sitio de soluciones para programar rompecabezas en el menor número de bytes. Hay una pregunta relacionada con esta: codegolf.stackexchange.com/q/96334/55572
Sergiy Kolodyazhnyy
4
¡Necesitamos más Java!
public class GetPathByLine{
public static void main(String[] args){for(String p :System.getenv("PATH").split(":")){System.out.println(p);}}}
Guarde esto GetPathByLine.javay compílelo usando:
javac GetPathByLine.java
Corre con:
java GetPathByLine
┌─[17:06:55]─[kazwolfe@BlackHawk]└──>~ $ cat GetPathByLine.java
public class GetPathByLine{
public static void main(String[] args){for(String p :System.getenv("PATH").split(":")){System.out.println(p);}}}┌─[17:06:58]─[kazwolfe@BlackHawk]└──>~ $ javac GetPathByLine.java
┌─[17:07:02]─[kazwolfe@BlackHawk]└──>~ $ java GetPathByLine/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
Short awk:echo $PATH | awk '{gsub(/\:/,"\n");print}'
Sergiy Kolodyazhnyy
I'mm no sé por qué te molestas con fileinputcuando uno podía utilizar input:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
wjandrea
2
Utilizo las "Funciones de ruta de acceso Bash" de Stephen Collyer (vea su artículo en Linux Journal ). Me permite usar la "lista separada por dos puntos" como un tipo de datos en la programación de shell. Por ejemplo, puedo generar una lista de todos los directorios en el directorio actual:
dirs="";for i in*;doif[-d $i ];then addpath -p dirs $i;fi;done
Expansión de parámetros de Shell : explica $ {parámetro / patrón / cadena}. Si el patrón comienza con '/', todas las coincidencias del patrón se reemplazan con una cadena.
Entonces tenemos:
un patrón /: que comienza con '/' para reemplazar todas las coincidencias
una cadena $ '\ n' que se cita con la contracción $ 'anytext' para tratar el nuevo símbolo de línea (\ n).
Otra forma AWK es tratar cada directorio como un registro separado , en lugar de como un campo separado .
awk 'BEGIN{RS=":"} {print $0}'<<<"$PATH"
Encuentro esa sintaxis particularmente intuitiva. Pero, si lo desea, puede acortarlo haciendo print $0implícito (es la acción predeterminada y se 1evalúa como verdadera, lo que hace que se haga para cada línea):
awk 'BEGIN{RS=":"} 1'<<<"$PATH"
El separador de registro de entrada y salida predeterminado de AWK es la nueva línea (salto de línea). Al configurar el separador de registro de entrada ( RS) :antes de leer la entrada, AWK analiza automáticamente un delimitado por dos puntos $PATHen sus nombres de directorio constitutivos. AWK se expande $0a cada registro completo, la nueva línea sigue siendo el separador de registros de salida , y no gsubse necesita hacer un bucle .
AWK a menudo se usa para analizar registros en campos separados, pero no hay necesidad de eso solo para construir una lista de nombres de directorio.
Esto funciona incluso para entradas que contienen espacios en blanco (espacios y pestañas), incluso múltiples espacios en blanco consecutivos:
ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}'<<<$'ab\t\t c:de fg:h'
ab c
de fg
h
Es decir, a menos que haga que AWK reconstruya el registro (consulte a continuación), no hay problema en tener espacios o pestañas (los separadores de campo predeterminados) en la entrada. Su PATHprobablemente no contiene espacios en un sistema Ubuntu, pero si lo hace, esto todavía va a funcionar.
Vale la pena mencionar, como nota al margen, que la capacidad de AWK de interpretar un registro como una colección de campos se vuelve útil para el problema relacionado de construir una tabla de componentes de directorio :
ek@Io:~$ awk -F/'BEGIN{RS=":"; OFS="\t"} {$1=$1; print $0}'<<<"$PATH"
home ek bin
usr local sbin
usr local bin
usr sbin
usr bin
sbin
bin
usr games
usr local games
snap bin
(Esto es probablemente más útil para casos en los que se debe realizar un procesamiento adicional en los componentes, que para el ejemplo exacto que se muestra de simplemente imprimir la tabla).
Estas son mis formas preferidas de hacerlo en función de mis respectivos casos de uso y preocupaciones sobre la compatibilidad y el uso de recursos.
tr
Primero, si necesita una solución rápida, fácil de recordar y legible, simplemente repítala y canalícela PATHpara traducir ( tr) para convertir los dos puntos en nuevas líneas:
echo $PATH | tr :"\n"
Tiene la desventaja de usar dos procesos debido a la tubería, pero si solo estamos pirateando una terminal, ¿realmente nos importa eso?
Expansión de parámetros de shell de Bash
Si desea una solución bastante permanente en su .bashrcuso interactivo, puede usar el alias del siguiente comando path, pero la legibilidad de esta solución es cuestionable:
alias path="echo \"${PATH//:/$'\n'}\""
Si el patrón comienza con '/', todas las coincidencias del patrón se reemplazan con una cadena. Normalmente solo se reemplaza el primer partido.
# v--v---------delimiters, a'la sed
echo "${PATH//:/$'\n'}"# ^^ ^^^^^----string, $ required to get newline character.# \----------pattern, / required to substitute for *every* :.
Buena suerte recordando esto cuando solo estás pirateando la línea de comando, si no lo has aliasado, sin embargo.
IFS, probado en Bash y Dash
Alternativamente, un enfoque bastante compatible, legible y comprensible que no se base en nada más que el shell es usar la siguiente función (sugiero en su .bashrc).
La siguiente función convierte temporalmente el separador de campo interno (o de entrada) (IFS) en dos puntos, y cuando se le da una matriz printf, se ejecuta hasta que la matriz se agote:
path (){local IFS=:
printf "%s\n" ${PATH}}
Este método de creación de la función , IFSy printfse proporcionan para por posix, así que debería funcionar en la mayoría posix-como conchas (especialmente DASH, que Ubuntu generalmente alias como sh).
Pitón
¿Deberías usar Python para esto? Tú podrías. Este es el comando Python más corto que se me ocurre para esto:
Respuestas:
Prueba
sed
:O
tr
:O
python
:Aquí todo lo anterior sustituirá todas las ocurrencias de
:
con nuevas líneas\n
.fuente
python -c 'import sys;print sys.argv[1].replace(":","\n")' $PATH
python -c "print r'$PATH'.replace(':', '\n')"
(usando una cadena cruda en caso de barras invertidas)tr
funcionó para mí (en mac, por cierto). Gracias..bash_profile
, agréguelo así:alias path='tr ":" "\n" <<< "$PATH"'
Utilice la expansión de parámetros de bash :
Todo esto sustituye
:
en$PATH
por un salto de línea (\n
) e imprime el resultado. El contenido de$PATH
permanece sin cambios.Si solo desea reemplazar el primero
:
, elimine la segunda barra:echo -e "${PATH/:/\n}"
fuente
${parameter/pattern/string}
Usando IFS:
IFS
contiene los caracteres en los que bash se divide, por lo que unIFS
con:
hace que bash divida la expansión de$PATH
on:
.printf
repite los argumentos sobre la cadena de formato hasta que se agoten los argumentos. Necesitamos deshabilitar el uso de globbing (expansión de comodines)set -f
para que los comodines en los nombres de directorio PATH no se expandan.fuente
Utilizando
xargs
:Desde
man xargs
fuente
echo $PATH | xargs -n1 -d: echo
ser redundante o no importa?echo $PATH | xargs -n1 -d:
hará lo mismo por ti, pero usarás un shell más. El primero evaluaráecho $PATH
y canalizará la salida al siguiente shell para hacer el resto.Aquí está el equivalente en Go:
fuente
Aquí hay algunos enfoques más. Estoy usando un
PATH
directorio con barras diagonales, espacios e incluso una nueva línea para mostrar que deberían funcionar con cualquier cosa (excepto lacut
que falla en las nuevas líneas):Algunas formas de Perl:
El
-p
medio "imprime cada línea de entrada después de aplicar la secuencia de comandos dada por-e
". El script está utilizando el operador de sustitución (s/oldnew/
) para reemplazar todo:
por líneas nuevas.El
-l
agrega una nueva línea a cadaprint
llamada. Aquí, el script está dividiendo su entrada:
y luego recorre cada elemento dividido y lo imprime.Las
-a
marcas seperl
comportan asíawk
: dividirá cada una de sus líneas de entrada en el carácter dado por-F
( por lo tanto:
, aquí) y guardará el resultado en la matriz@F
. El$"
es una variable especial de Perl, el "separador de lista", cuyo valor se imprime entre cada elemento de una lista impresa. Por lo tanto, establecerlo en una nueva línea hará que seprint @list
imprima cada elemento@list
y luego una nueva línea. Aquí, lo estamos usando para imprimir@F
.La misma idea que la anterior, solo que menos golf. En lugar de usar
$"
, estamos explícitamentejoin
agregando nuevas líneas y luego imprimiendo.Simple
grep
con PCRE magic:Las
-o
marcasgrep
imprimir solamente la parte correspondiente de cada línea, por lo que cada partido se imprime en una línea separada. El-P
permite Perl Compatible Regular Expressions (PCRE). La expresión regular busca extensiones de no-:
([^:]+
) que siguen al principio de la línea (^
) o un:
carácter. El\K
es un truco PCRE que significa "descartar cualquier cosa que coincida antes de este punto" y se usa aquí para evitar imprimir:
también.Y una
cut
solución (esta falla en las nuevas líneas, pero puede tratar con barras invertidas y espacios):Las opciones utilizadas son las
-d:
que configuran el delimitador de entrada:
, lo-f 1-
que significa imprimir todos los campos (desde el primero hasta el final) y lo--output-delimiter=$'\n'
que configura el delimitador de salida. El$'\n'
es ANSI C citando y es una manera de imprimir un carácter de nueva línea en la cáscara.En todos los ejemplos anteriores, estoy usando el operador string (
<<<
) here de bash (y algunos otros shells ) para pasar una cadena como entrada a un programa. Entoncescommand <<<"foo"
es equivalente aecho -n "foo" | command
. Tenga en cuenta que siempre estoy citando"$PATH"
, sin las comillas, el shell habría comido el carácter de nueva línea.@ 7stud dio otro enfoque en los comentarios que es demasiado bueno para no incluir:
Eso es lo que se conoce como golf . El
-0
especifica el separador de registro de entrada como un número octal o hexadecimal. Esto es lo que define una "línea" y su valor predeterminado es\n
un carácter de nueva línea. Aquí, lo estamos configurando en un:
que estáx3a
en hexadecimal (tryprintf '\x3a\n'
). El-l
hace tres cosas. Primero, elimina el separador de registro de entrada ($/
) del final de cada línea, eliminando efectivamente el:
aquí, y segundo, establece el separador de registro de salida ($\
) a cualquier valor octal o hexadecimal que se le dé (012
es\n
). Si$\
se define, se agrega al final de cadaprint
llamada, por lo que se agregará una nueva línea a cada unaprint
.La
-pe
voluntad p rint cada línea de entrada después de aplicar la secuencia de comandos dada por-e
. ¡Aquí no hay script porque todo el trabajo se realiza mediante las banderas de opciones como se describe arriba!fuente
perl -0x3a -l012 -pe '' <<<$PATH
. Explicación:-0
establece el separador de registro de entrada (especificado en notación hexadecimal / octal, x3A es un signo de dos puntos),-l
hace dos cosas: 1) divide el separador de registro de entrada, 2) establece el separador de registro de salida si se especifica uno (en notación octal) , 012 es una nueva línea). Un-p
bucle imprime el valor de $ _, que será leído en cada línea .-F
puede eliminar los-a
y las-n
banderas, como -F convierte automáticamente en los que:perl -F: -e 'print(join "\n", @F);' <<<$PATH
. Ver perlrun . Buenos ejemplos.-F
información. He estado usando-F
combinados-an
durante años, nunca me di cuenta de que uno implicaba a los demás. Por cierto, vi que Serg mencionaba Code Golf , pero creo que también disfrutarías de Unix y Linux si te gusta este tipo de cosas.-l
también agrega el separador de registro de salida dado al final de cada llamada impresa. De hecho, print siempre agrega el separador de registro de salida,,$/
al final de una cadena, si el separador de registro de salida está definido. Por defecto es undef. Entonces,-l
jus establece$/
, y eso hace que print agregue la nueva línea al final de la cadena.Probablemente, la única forma en que no se ha mencionado es la forma en que lo he estado usando durante años:
echo $PATH | tr ":" "\n"
entonces, en su .profile o .bash_profile o lo que sea, puede agregar:
alias path='echo $PATH | tr ":" "\n"'
fuente
En esta respuesta:
1. C
Como ya se han tomado todos los lenguajes de secuencias de comandos, iré con C. Es bastante fácil obtener variables de entorno con
get_env()
función (consulte la documentación de la Biblioteca GNU C ). El resto es simplemente manipulación de personajes.2. Python
Pero también porque "por qué no", aquí hay una versión alternativa de Python a través de argumentos de línea de comando
sys.argv
3. Ruby
Ruby no viene con Ubuntu por defecto, a diferencia del compilador de C y el intérprete de Python, pero si alguna vez lo usa, la solución en Ruby sería esta:
Como lo sugirió 7stud (¡Muchas gracias!) En los comentarios , esto también se puede acortar con
y de esta manera
4. awk alternativo
Podemos utilizar la
split()
función para desglosar la línea leída en una matriz y usar elfor-each
bucle para imprimir cada elemento en una línea separada.fuente
puts
¡Imprime automáticamente los elementos de una matriz en líneas separadas! También puede hacer que los interruptores hagan la división:ruby -F: -ane 'puts $F' <<<$PATH
Explicación: se-F
establece$;
en el carácter especificado, que es el separador predeterminado utilizado por String :: split ($; tiene un valor predeterminado de nil, que se divide en espacios en blanco).-a
llama a $ _. split, donde $ _ es una línea leída usando gets ()) y asigna la matriz resultante a$F
.-F
bandera, recién estoy comenzando con Ruby, así que estoy haciendo las cosas de una manera un poco tosca.ruby -0072 -ne 'puts chomp' <<<$PATH
. Explicación:-0
establece el separador de registro de entrada (especifique un carácter en formato octal; 072 es dos puntos). Ruby emplea $ _ de manera similar a Perl. El método gets () (usado en el-n
bucle) establece $ _ en la línea actual que se lee. Ychomp()
sin un argumento, muerde $ _. Todavía me gusta más el tuyo. :)-F
bandera, es más corto. Si lo hace,echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c
me dice que es 271, bytes, pero el número octal es 276. Eso es para todo el comando, por supuesto, si consideramos que solo el código en síputs $F
es claramente más corto. :) Por cierto, ¿sabes sobre Code Golf ? Es el sitio de soluciones para programar rompecabezas en el menor número de bytes. Hay una pregunta relacionada con esta: codegolf.stackexchange.com/q/96334/55572¡Necesitamos más Java!
Guarde esto
GetPathByLine.java
y compílelo usando:Corre con:
fuente
python3 -c "import os; [print(p) for p in os.getenv('PATH').split(':')]"
A través de awk.
A través de pitón.
Tenga en cuenta que la sangría es muy importante en Python.
fuente
echo $PATH | awk '{gsub(/\:/,"\n");print}'
fileinput
cuando uno podía utilizarinput
:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
Utilizo las "Funciones de ruta de acceso Bash" de Stephen Collyer (vea su artículo en Linux Journal ). Me permite usar la "lista separada por dos puntos" como un tipo de datos en la programación de shell. Por ejemplo, puedo generar una lista de todos los directorios en el directorio actual:
Luego,
listpath -p dirs
produce una lista.fuente
Explicación para la respuesta @Cyrus
Notas:
Cita ANSI-C : explica $ 'some \ ntext'
Expansión de parámetros de Shell : explica $ {parámetro / patrón / cadena}. Si el patrón comienza con '/', todas las coincidencias del patrón se reemplazan con una cadena.
Entonces tenemos:
fuente
Otra forma AWK es tratar cada directorio como un registro separado , en lugar de como un campo separado .
Encuentro esa sintaxis particularmente intuitiva. Pero, si lo desea, puede acortarlo haciendo
print $0
implícito (es la acción predeterminada y se1
evalúa como verdadera, lo que hace que se haga para cada línea):El separador de registro de entrada y salida predeterminado de AWK es la nueva línea (salto de línea). Al configurar el separador de registro de entrada (
RS
):
antes de leer la entrada, AWK analiza automáticamente un delimitado por dos puntos$PATH
en sus nombres de directorio constitutivos. AWK se expande$0
a cada registro completo, la nueva línea sigue siendo el separador de registros de salida , y nogsub
se necesita hacer un bucle .AWK a menudo se usa para analizar registros en campos separados, pero no hay necesidad de eso solo para construir una lista de nombres de directorio.
Esto funciona incluso para entradas que contienen espacios en blanco (espacios y pestañas), incluso múltiples espacios en blanco consecutivos:
Es decir, a menos que haga que AWK reconstruya el registro (consulte a continuación), no hay problema en tener espacios o pestañas (los separadores de campo predeterminados) en la entrada. Su
PATH
probablemente no contiene espacios en un sistema Ubuntu, pero si lo hace, esto todavía va a funcionar.Vale la pena mencionar, como nota al margen, que la capacidad de AWK de interpretar un registro como una colección de campos se vuelve útil para el problema relacionado de construir una tabla de componentes de directorio :
La curiosa
$1=$1
asignación sirve para forzar a AWK a reconstruir el registro .(Esto es probablemente más útil para casos en los que se debe realizar un procesamiento adicional en los componentes, que para el ejemplo exacto que se muestra de simplemente imprimir la tabla).
fuente
fuente
Estas son mis formas preferidas de hacerlo en función de mis respectivos casos de uso y preocupaciones sobre la compatibilidad y el uso de recursos.
tr
Primero, si necesita una solución rápida, fácil de recordar y legible, simplemente repítala y canalícela
PATH
para traducir (tr
) para convertir los dos puntos en nuevas líneas:Tiene la desventaja de usar dos procesos debido a la tubería, pero si solo estamos pirateando una terminal, ¿realmente nos importa eso?
Expansión de parámetros de shell de Bash
Si desea una solución bastante permanente en su
.bashrc
uso interactivo, puede usar el alias del siguiente comandopath
, pero la legibilidad de esta solución es cuestionable:El comando anterior sustituye los dos puntos con nuevas líneas utilizando la expansión de parámetros de Shell de Bash :
Para explicarlo:
Buena suerte recordando esto cuando solo estás pirateando la línea de comando, si no lo has aliasado, sin embargo.
IFS, probado en Bash y Dash
Alternativamente, un enfoque bastante compatible, legible y comprensible que no se base en nada más que el shell es usar la siguiente función (sugiero en su
.bashrc
).La siguiente función convierte temporalmente el separador de campo interno (o de entrada) (IFS) en dos puntos, y cuando se le da una matriz
printf
, se ejecuta hasta que la matriz se agote:Este método de creación de la función ,
IFS
yprintf
se proporcionan para por posix, así que debería funcionar en la mayoría posix-como conchas (especialmente DASH, que Ubuntu generalmente alias comosh
).Pitón
¿Deberías usar Python para esto? Tú podrías. Este es el comando Python más corto que se me ocurre para esto:
o solo Python 3 (¿y quizás más legible?):
También deberían funcionar en cualquier entorno de shell habitual, siempre que tenga Python.
fuente
Esta solución es más simple que las soluciones Java , C , go y awk :
Aquí hay otra gran posibilidad:
Esto requeriría instalar algunas dependencias:
fuente