Tudo isso substitui :em $PATHpor uma nova linha ( \n) e imprime o resultado. O conteúdo de $PATHpermanece inalterado.
Se você deseja substituir apenas o primeiro :, remova a segunda barra:echo -e "${PATH/:/\n}"
Penso que esta é a melhor solução porque é feita em pura festa.
Ryanmjacobs 22/03
1
@ryanmjacobs levemente curioso: o que você acha que minha solução usa? : D
muru 23/03
1
por favor, explique como isso funciona.
Tulains Córdova 23/03
Como é chamado esse tipo de operação? É semelhante ao sed, mas não é sed. Qual é o nome dele para que eu possa pesquisar na web para obter mais informações sobre ele.
Tulains Córdova 23/03
3
Siga o link (expansão de parâmetro) na minha resposta e role para baixo até a última segunda seção chamada:${parameter/pattern/string}
Cyrus
27
Usando IFS:
(set-f; IFS=:; printf "%s\n" $PATH)
IFSmantém os caracteres nos quais o bash se divide, portanto, um IFScom :faz com que o bash divida a expansão de $PATHon :. printffaz um loop dos argumentos sobre a string de formato até que os argumentos se esgotem. Precisamos desativar o globbing (expansão de curinga) usando set -fpara que os curingas nos nomes de diretório PATH não sejam expandidos.
haveria variação nisso, como echo $PATH | xargs -n1 -d: echoredundante ou não importa?
Sergiy Kolodyazhnyy
O @Serg echo $PATH | xargs -n1 -d: fará o mesmo por você, mas você usará mais um shell. O primeiro avaliará echo $PATHe canalizará a saída para o próximo shell para fazer o resto.
Souravc
7
Aqui está o equivalente em 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
Aqui estão mais algumas abordagens. Estou usando um PATHcom diretórios contendo barras invertidas, espaços e até uma nova linha para mostrar que eles devem funcionar com qualquer coisa (exceto a cutque falha em novas linhas):
$ echo "$PATH"/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even
new lines
O -pmeio "imprime todas as linhas de entrada após aplicar o script fornecido por -e". O script está usando o operador de substituição ( s/oldnew/) para substituir todos :por novas linhas.
$ perl -lne 'print for split /:/'<<<"$PATH"/bin
usr/bin//usr/local/bin
/some\ horrible thing
/even
new lines
O -ladiciona uma nova linha a cada printchamada. Aqui, o script está dividindo sua entrada :e, em seguida, faz um loop sobre cada elemento de divisão e a imprime.
As -amarcas perlse comportam assim awk: dividirá cada uma de suas linhas de entrada no caractere fornecido por -F(então :, aqui) e salvará o resultado na matriz @F. A $"é uma variável especial Perl, o "separador de lista", cujo valor é impressa entre cada elemento de uma lista impressa. Portanto, defini-lo como uma nova linha fará com que print @listcada elemento seja impresso @liste, em seguida, uma nova linha. Aqui, estamos usando-o para imprimir @F.
O -ofaz grepimprimir apenas a parte correspondente de cada linha, para que cada correspondência seja impressa em uma linha separada. O -Ppermite Perl Compatible Regular Expressions (PCRE). O regex está procurando trechos de não :( [^:]+) que seguem o início da linha ( ^) ou um :caractere. O \Ké um truque PCRE que significa "nada descarte combinado antes deste ponto" e é usado aqui para evitar a impressão do :bem.
E uma cutsolução (essa falha nas novas linhas, mas pode lidar com barras invertidas e espaços):
As opções utilizadas são: -d:define o delimitador de entrada :, o -f 1-que significa imprimir todos os campos (do 1º ao final) e --output-delimiter=$'\n'define o delimitador de saída. A citação$'\n' é ANSI C e é uma maneira de imprimir um caractere de nova linha no shell.
Em todos os exemplos acima, estou usando o operador string ( <<<) de bash (e alguns outros shells) aqui para passar uma string como entrada para um programa. Então command <<<"foo"é equivalente a echo -n "foo" | command. Observe que estou sempre citando "$PATH", sem as aspas, o shell teria comido o caractere de nova linha.
Isso é conhecido como golfe . O -0especifica o separador de registro de entrada como um número octal ou hexadecimal. É isso que define uma "linha" e seu valor padrão é \num caractere de nova linha. Aqui, estamos definindo-o como um :que está x3aem hexadecimal (tentativa printf '\x3a\n'). O -lfaz três coisas. Primeiro, ele remove o separador de registro de entrada ( $/) do final de cada linha - removendo efetivamente o :here - e, em segundo lugar, define o separador de registro de saída ( $\) para qualquer valor octal ou hexadecimal que for dado ( 012é \n). Se $\definido, ele será adicionado ao final de cada printchamada, resultando em uma nova linha anexada a cada uma print.
A -pevontade p rint cada linha de entrada após a aplicação do roteiro dada por -e. Aqui não há script, porque todo o trabalho é realizado pelos sinalizadores de opção, conforme descrito acima!
Seus liners perl one não são suficientemente obscuros! Aqui está uma versão em que não há nenhum código para a opção -e para executar porque os outros switches lidar com tudo: perl -0x3a -l012 -pe '' <<<$PATH. Explicação: -0define o separador de registros de entrada (especificado em notação hex / octal, x3A é dois pontos), -lfaz duas coisas: 1) chomps o separador de registros de entrada, 2) define o separador de registros de saída se um for especificado (em notação octal , 012 é uma nova linha). Um -ploop imprime o valor de $ _, que será lido em cada linha .
7stud
Observe também que os exemplos usando -Fpode eliminar os -ae -nbandeiras, como -F transforma aqueles em automaticamente perl -F: -e 'print(join "\n", @F);' <<<$PATH. Veja perlrun . Bons exemplos.
7stud
@ 7stud wow, isso é realmente brilhante, obrigado! Roubado descaradamente e adicionado à minha resposta (presumo que você não se importe, fique à vontade para postá-la como resposta e eu a excluirei). E obrigado pela -Finformação. Eu uso -Fcombinado -anhá anos, nunca percebi que um implicava os outros. A propósito, vi Serg mencionando o Code Golf , mas acho que você também gostaria de Unix e Linux se você gosta desse tipo de coisa.
terdon
Ei, obrigado. Um esclarecimento sobre esta afirmação: Finalmente, -ltambém adiciona o separador de registros de saída fornecido ao final de cada chamada de impressão. De fato, a impressão sempre adiciona o separador de registros de saída,, $/ao final de uma string - se o separador de registros de saída estiver definido. Por padrão, é undef. Então, -ljus define $/e isso faz com que o print adicione a nova linha no final da string.
7stud
Presumo que você não se importe - de maneira alguma. :)
7stud
6
Nesta resposta:
C
Pitão
Rubi
Awk alternativo
1. C
Como todas as linguagens de script já foram utilizadas, irei com o C. É muito fácil obter variáveis de ambiente com a get_env()função (consulte a documentação da GNU C Library ). O resto é simplesmente manipulação de caracteres
O Ruby não vem com o Ubuntu por padrão, ao contrário do compilador C e do interpretador Python, mas se você o usar, a solução no Ruby seria a seguinte:
ruby -ne 'puts $_.split(":")'<<<"$PATH"
Como sugerido pelo 7stud (Muito obrigado!) Nos comentários , isso também pode ser abreviado com
Belo exemplo de rubi. putsimprime automaticamente os elementos de uma matriz em linhas separadas! Você também pode fazer com que os comutadores façam a divisão: ruby -F: -ane 'puts $F' <<<$PATH Explicação: -Fdefine $;o caractere especificado, que é o separador padrão usado por String :: split ($; tem um valor padrão nil, que se divide em espaço em branco). -achama $ _. split, onde $ _ é uma linha lida usando gets ()) e atribui a matriz resultante a $F.
7stud
@ 7stud hey, obrigado! :) Não sabia da -Fbandeira - estou apenas começando com Ruby, fazendo as coisas de maneira um pouco grosseira.
Sergiy Kolodyazhnyy
Não, isso é coisa obscura. Seu liner é muito legível e a clareza deve prevalecer sobre a brevidade todas as vezes.
7stud
Hah. Eu descobri um mais curto: ruby -0072 -ne 'puts chomp' <<<$PATH. Explicação: -0define o separador de registro de entrada (especifique um caractere no formato octal; 072 é dois pontos). Ruby emprega $ _ de maneira semelhante ao Perl. O método gets () (usado no -nloop) define $ _ para a linha atual que é lida. E chomp()sem um argumento, chomps $ _. Eu ainda gosto mais do seu. :)
7stud
@ 7stud, na verdade, o que você postou anteriormente, com -Fsinalizador, é mais curto. Se você fizer echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c isso, me informará que são 271 bytes, mas o número octal é 276. Isso é para todo o comando, é claro, se considerarmos que apenas o código em si puts $Fé claramente mais curto. :) A propósito, você conhece o Code Golf ? É o site de soluções para a programação de quebra-cabeças no menor número de bytes. Há uma questão relacionada com esta: codegolf.stackexchange.com/q/96334/55572
Sergiy Kolodyazhnyy
5
Provavelmente, a única maneira que não foi mencionada é a maneira que eu a uso há anos:
echo $PATH | tr ":" "\n"
portanto, em seu .profile ou .bash_profile ou o que for, você pode adicionar:
Mais curto awk:echo $PATH | awk '{gsub(/\:/,"\n");print}'
Sergiy Kolodyazhnyy 14/10
I'mm não sei por que você se preocupar com fileinputquando você pode simplesmente usar input:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
wjandrea
2
Eu uso "Bash Path Functions" de Stephen Collyer (veja seu artigo no Linux Journal ). Permite-me usar a "lista separada por dois pontos" como um tipo de dados na programação shell. Por exemplo, eu posso produzir uma lista de todos os diretórios no diretório atual:
dirs="";for i in*;doif[-d $i ];then addpath -p dirs $i;fi;done
Expansão de parâmetros do shell - explica $ {parameter / pattern / string}. Se o padrão começa com '/', todas as correspondências do padrão são substituídas por string.
Então nós temos:
um padrão /: que começa com '/' para substituir todas as correspondências
uma string $ '\ n' que é citada com a contração $ 'anytext' para tratar o novo símbolo de linha (\ n).
Outra maneira do AWK é tratar cada diretório como um registro separado , e não como um campo separado .
awk 'BEGIN{RS=":"} {print $0}'<<<"$PATH"
Acho essa sintaxe particularmente intuitiva. Mas, se quiser, você pode reduzi-lo, tornando print $0implícito (é a ação padrão e 1avalia como verdadeira, fazendo com que seja feito para cada linha):
awk 'BEGIN{RS=":"} 1'<<<"$PATH"
O separador de registro de entrada e saída padrão do AWK é a nova linha (quebra de linha). Ao definir o separador de registros de entrada ( RS) como :antes de ler a entrada, o AWK analisa automaticamente dois pontos delimitados por dois pontos $PATHem seus nomes de diretório constitutivos. O AWK se expande $0para cada registro inteiro, a nova linha continua sendo o separador de registros de saída e não gsubé necessário fazer loop ou é necessário.
O AWK é frequentemente usado para analisar registros em campos separados, mas não há necessidade disso apenas para construir uma lista de nomes de diretórios.
Isso funciona mesmo para entradas que contêm espaços em branco (espaços e tabulações), até vários espaços em branco consecutivos:
ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}'<<<$'ab\t\t c:de fg:h'
ab c
de fg
h
Ou seja, a menos que você faça com que o AWK reconstrua o registro (veja abaixo), não há problema em ter espaços ou tabulações (os separadores de campo padrão) na entrada. Seu PATHprovavelmente não contém espaços em um sistema Ubuntu, mas se isso acontecer, isso ainda vai funcionar.
Vale ressaltar, como observação lateral, que a capacidade do AWK de interpretar um registro como uma coleção de campos se torna útil para o problema relacionado de construir uma tabela de componentes de diretório :
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
(Isso é provavelmente mais útil nos casos em que um processamento adicional deve ser feito nos componentes, do que no exemplo exato mostrado simplesmente da impressão da tabela.)
Essas são as minhas maneiras preferidas de fazer isso com base nos meus respectivos casos de uso e preocupações sobre compatibilidade e uso de recursos.
tr
Primeiro, se você precisar de uma solução rápida, fácil de lembrar e legível, basta fazer eco PATHe canalizá-la para translate ( tr) para transformar os dois pontos em novas linhas:
echo $PATH | tr :"\n"
Ele tem a desvantagem de usar dois processos por causa do canal, mas se estamos apenas invadindo um terminal, realmente nos importamos com isso?
Expansão do parâmetro shell do Bash
Se você deseja uma solução bastante permanente .bashrcpara uso interativo, pode usar o seguinte comando path, mas a legibilidade dessa solução é questionável:
alias path="echo \"${PATH//:/$'\n'}\""
Se o padrão começar com '/', todas as correspondências do padrão serão substituídas por uma sequência. Normalmente, apenas a primeira partida é substituída.
# v--v---------delimiters, a'la sed
echo "${PATH//:/$'\n'}"# ^^ ^^^^^----string, $ required to get newline character.# \----------pattern, / required to substitute for *every* :.
Boa sorte lembrando-se disso quando você está apenas invadindo a linha de comando, se ainda não tiver o alias.
IFS, testado no Bash and Dash
Como alternativa, uma abordagem razoavelmente compatível, legível e compreensível que não dependa de nada além do shell é usar a seguinte função (sugiro no seu .bashrc.)
A função a seguir transforma temporariamente o Separador de Campo Interno (ou Entrada) (IFS) em dois pontos e, quando uma matriz é fornecida printf, ela é executada até que a matriz seja usada:
path (){local IFS=:
printf "%s\n" ${PATH}}
Este método de criação da função , IFSe printfsão fornecidos pelo POSIX, assim que deve funcionar na maioria POSIX-como conchas (especialmente Dash, que Ubuntu geralmente aliases como sh).
Pitão
Você deve usar o Python para isso? Você poderia. Este é o comando Python mais curto que consigo pensar nisso:
Respostas:
Tente
sed
:Ou
tr
:Ou
python
:Aqui, todos os itens acima substituirão todas as ocorrências de
:
por novas linhas\n
.fonte
python -c 'import sys;print sys.argv[1].replace(":","\n")' $PATH
python -c "print r'$PATH'.replace(':', '\n')"
(usando uma corda em bruto no caso de barras invertidas)tr
trabalhou para mim (no mac, aliás). Obrigado..bash_profile
, adicione-os assim: #alias path='tr ":" "\n" <<< "$PATH"'
Use a expansão de parâmetros do bash :
Tudo isso substitui
:
em$PATH
por uma nova linha (\n
) e imprime o resultado. O conteúdo de$PATH
permanece inalterado.Se você deseja substituir apenas o primeiro
:
, remova a segunda barra:echo -e "${PATH/:/\n}"
fonte
${parameter/pattern/string}
Usando IFS:
IFS
mantém os caracteres nos quais o bash se divide, portanto, umIFS
com:
faz com que o bash divida a expansão de$PATH
on:
.printf
faz um loop dos argumentos sobre a string de formato até que os argumentos se esgotem. Precisamos desativar o globbing (expansão de curinga) usandoset -f
para que os curingas nos nomes de diretório PATH não sejam expandidos.fonte
Usando
xargs
:De
man xargs
fonte
echo $PATH | xargs -n1 -d: echo
redundante ou não importa?echo $PATH | xargs -n1 -d:
fará o mesmo por você, mas você usará mais um shell. O primeiro avaliaráecho $PATH
e canalizará a saída para o próximo shell para fazer o resto.Aqui está o equivalente em Go:
fonte
Aqui estão mais algumas abordagens. Estou usando um
PATH
com diretórios contendo barras invertidas, espaços e até uma nova linha para mostrar que eles devem funcionar com qualquer coisa (exceto acut
que falha em novas linhas):Algumas maneiras Perl:
O
-p
meio "imprime todas as linhas de entrada após aplicar o script fornecido por-e
". O script está usando o operador de substituição (s/oldnew/
) para substituir todos:
por novas linhas.O
-l
adiciona uma nova linha a cadaprint
chamada. Aqui, o script está dividindo sua entrada:
e, em seguida, faz um loop sobre cada elemento de divisão e a imprime.As
-a
marcasperl
se comportam assimawk
: dividirá cada uma de suas linhas de entrada no caractere fornecido por-F
(então:
, aqui) e salvará o resultado na matriz@F
. A$"
é uma variável especial Perl, o "separador de lista", cujo valor é impressa entre cada elemento de uma lista impressa. Portanto, defini-lo como uma nova linha fará com queprint @list
cada elemento seja impresso@list
e, em seguida, uma nova linha. Aqui, estamos usando-o para imprimir@F
.A mesma idéia acima, apenas menos golfe. Em vez de usar
$"
, estamos explicitamentejoin
inserindo a matriz com novas linhas e depois imprimindo.Simples
grep
com a magia PCRE:O
-o
fazgrep
imprimir apenas a parte correspondente de cada linha, para que cada correspondência seja impressa em uma linha separada. O-P
permite Perl Compatible Regular Expressions (PCRE). O regex está procurando trechos de não:
([^:]+
) que seguem o início da linha (^
) ou um:
caractere. O\K
é um truque PCRE que significa "nada descarte combinado antes deste ponto" e é usado aqui para evitar a impressão do:
bem.E uma
cut
solução (essa falha nas novas linhas, mas pode lidar com barras invertidas e espaços):As opções utilizadas são:
-d:
define o delimitador de entrada:
, o-f 1-
que significa imprimir todos os campos (do 1º ao final) e--output-delimiter=$'\n'
define o delimitador de saída. A citação$'\n'
é ANSI C e é uma maneira de imprimir um caractere de nova linha no shell.Em todos os exemplos acima, estou usando o operador string (
<<<
) de bash (e alguns outros shells) aqui para passar uma string como entrada para um programa. Entãocommand <<<"foo"
é equivalente aecho -n "foo" | command
. Observe que estou sempre citando"$PATH"
, sem as aspas, o shell teria comido o caractere de nova linha.O @ 7stud deu outra abordagem nos comentários, que é boa demais para não incluir:
Isso é conhecido como golfe . O
-0
especifica o separador de registro de entrada como um número octal ou hexadecimal. É isso que define uma "linha" e seu valor padrão é\n
um caractere de nova linha. Aqui, estamos definindo-o como um:
que estáx3a
em hexadecimal (tentativaprintf '\x3a\n'
). O-l
faz três coisas. Primeiro, ele remove o separador de registro de entrada ($/
) do final de cada linha - removendo efetivamente o:
here - e, em segundo lugar, define o separador de registro de saída ($\
) para qualquer valor octal ou hexadecimal que for dado (012
é\n
). Se$\
definido, ele será adicionado ao final de cadaprint
chamada, resultando em uma nova linha anexada a cada umaprint
.A
-pe
vontade p rint cada linha de entrada após a aplicação do roteiro dada por-e
. Aqui não há script, porque todo o trabalho é realizado pelos sinalizadores de opção, conforme descrito acima!fonte
perl -0x3a -l012 -pe '' <<<$PATH
. Explicação:-0
define o separador de registros de entrada (especificado em notação hex / octal, x3A é dois pontos),-l
faz duas coisas: 1) chomps o separador de registros de entrada, 2) define o separador de registros de saída se um for especificado (em notação octal , 012 é uma nova linha). Um-p
loop imprime o valor de $ _, que será lido em cada linha .-F
pode eliminar os-a
e-n
bandeiras, como -F transforma aqueles em automaticamenteperl -F: -e 'print(join "\n", @F);' <<<$PATH
. Veja perlrun . Bons exemplos.-F
informação. Eu uso-F
combinado-an
há anos, nunca percebi que um implicava os outros. A propósito, vi Serg mencionando o Code Golf , mas acho que você também gostaria de Unix e Linux se você gosta desse tipo de coisa.-l
também adiciona o separador de registros de saída fornecido ao final de cada chamada de impressão. De fato, a impressão sempre adiciona o separador de registros de saída,,$/
ao final de uma string - se o separador de registros de saída estiver definido. Por padrão, é undef. Então,-l
jus define$/
e isso faz com que o print adicione a nova linha no final da string.Nesta resposta:
1. C
Como todas as linguagens de script já foram utilizadas, irei com o C. É muito fácil obter variáveis de ambiente com a
get_env()
função (consulte a documentação da GNU C Library ). O resto é simplesmente manipulação de caracteres2. Python
Mas também porque "por que não", aqui está a versão alternativa do python via argumentos da linha de comando
sys.argv
3. Ruby
O Ruby não vem com o Ubuntu por padrão, ao contrário do compilador C e do interpretador Python, mas se você o usar, a solução no Ruby seria a seguinte:
Como sugerido pelo 7stud (Muito obrigado!) Nos comentários , isso também pode ser abreviado com
e assim
4. Awk alternativo
Podemos utilizar a
split()
função para dividir a linha lida em matriz e usar ofor-each
loop para imprimir cada item em uma linha separada.fonte
puts
imprime automaticamente os elementos de uma matriz em linhas separadas! Você também pode fazer com que os comutadores façam a divisão:ruby -F: -ane 'puts $F' <<<$PATH
Explicação:-F
define$;
o caractere especificado, que é o separador padrão usado por String :: split ($; tem um valor padrão nil, que se divide em espaço em branco).-a
chama $ _. split, onde $ _ é uma linha lida usando gets ()) e atribui a matriz resultante a$F
.-F
bandeira - estou apenas começando com Ruby, fazendo as coisas de maneira um pouco grosseira.ruby -0072 -ne 'puts chomp' <<<$PATH
. Explicação:-0
define o separador de registro de entrada (especifique um caractere no formato octal; 072 é dois pontos). Ruby emprega $ _ de maneira semelhante ao Perl. O método gets () (usado no-n
loop) define $ _ para a linha atual que é lida. Echomp()
sem um argumento, chomps $ _. Eu ainda gosto mais do seu. :)-F
sinalizador, é mais curto. Se você fizerecho "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c
isso, me informará que são 271 bytes, mas o número octal é 276. Isso é para todo o comando, é claro, se considerarmos que apenas o código em siputs $F
é claramente mais curto. :) A propósito, você conhece o Code Golf ? É o site de soluções para a programação de quebra-cabeças no menor número de bytes. Há uma questão relacionada com esta: codegolf.stackexchange.com/q/96334/55572Provavelmente, a única maneira que não foi mencionada é a maneira que eu a uso há anos:
echo $PATH | tr ":" "\n"
portanto, em seu .profile ou .bash_profile ou o que for, você pode adicionar:
alias path='echo $PATH | tr ":" "\n"'
fonte
Precisamos de mais Java!
Salve isso
GetPathByLine.java
e compile usando:Correr com:
fonte
python3 -c "import os; [print(p) for p in os.getenv('PATH').split(':')]"
Através do awk.
Através de python.
Observe que o recuo é muito importante em python.
fonte
echo $PATH | awk '{gsub(/\:/,"\n");print}'
fileinput
quando você pode simplesmente usarinput
:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
Eu uso "Bash Path Functions" de Stephen Collyer (veja seu artigo no Linux Journal ). Permite-me usar a "lista separada por dois pontos" como um tipo de dados na programação shell. Por exemplo, eu posso produzir uma lista de todos os diretórios no diretório atual:
Então,
listpath -p dirs
produz uma lista.fonte
Explicação da resposta @Cyrus
Notas:
Citação ANSI-C - explica $ 'some \ ntext'
Expansão de parâmetros do shell - explica $ {parameter / pattern / string}. Se o padrão começa com '/', todas as correspondências do padrão são substituídas por string.
Então nós temos:
fonte
Outra maneira do AWK é tratar cada diretório como um registro separado , e não como um campo separado .
Acho essa sintaxe particularmente intuitiva. Mas, se quiser, você pode reduzi-lo, tornando
print $0
implícito (é a ação padrão e1
avalia como verdadeira, fazendo com que seja feito para cada linha):O separador de registro de entrada e saída padrão do AWK é a nova linha (quebra de linha). Ao definir o separador de registros de entrada (
RS
) como:
antes de ler a entrada, o AWK analisa automaticamente dois pontos delimitados por dois pontos$PATH
em seus nomes de diretório constitutivos. O AWK se expande$0
para cada registro inteiro, a nova linha continua sendo o separador de registros de saída e nãogsub
é necessário fazer loop ou é necessário.O AWK é frequentemente usado para analisar registros em campos separados, mas não há necessidade disso apenas para construir uma lista de nomes de diretórios.
Isso funciona mesmo para entradas que contêm espaços em branco (espaços e tabulações), até vários espaços em branco consecutivos:
Ou seja, a menos que você faça com que o AWK reconstrua o registro (veja abaixo), não há problema em ter espaços ou tabulações (os separadores de campo padrão) na entrada. Seu
PATH
provavelmente não contém espaços em um sistema Ubuntu, mas se isso acontecer, isso ainda vai funcionar.Vale ressaltar, como observação lateral, que a capacidade do AWK de interpretar um registro como uma coleção de campos se torna útil para o problema relacionado de construir uma tabela de componentes de diretório :
A
$1=$1
designação curiosa serve para forçar o AWK a reconstruir o registro .(Isso é provavelmente mais útil nos casos em que um processamento adicional deve ser feito nos componentes, do que no exemplo exato mostrado simplesmente da impressão da tabela.)
fonte
fonte
Essas são as minhas maneiras preferidas de fazer isso com base nos meus respectivos casos de uso e preocupações sobre compatibilidade e uso de recursos.
tr
Primeiro, se você precisar de uma solução rápida, fácil de lembrar e legível, basta fazer eco
PATH
e canalizá-la para translate (tr
) para transformar os dois pontos em novas linhas:Ele tem a desvantagem de usar dois processos por causa do canal, mas se estamos apenas invadindo um terminal, realmente nos importamos com isso?
Expansão do parâmetro shell do Bash
Se você deseja uma solução bastante permanente
.bashrc
para uso interativo, pode usar o seguinte comandopath
, mas a legibilidade dessa solução é questionável:O comando acima substitui os dois pontos por novas linhas usando a expansão de parâmetros de shell do Bash :
Para explicar isso:
Boa sorte lembrando-se disso quando você está apenas invadindo a linha de comando, se ainda não tiver o alias.
IFS, testado no Bash and Dash
Como alternativa, uma abordagem razoavelmente compatível, legível e compreensível que não dependa de nada além do shell é usar a seguinte função (sugiro no seu
.bashrc
.)A função a seguir transforma temporariamente o Separador de Campo Interno (ou Entrada) (IFS) em dois pontos e, quando uma matriz é fornecida
printf
, ela é executada até que a matriz seja usada:Este método de criação da função ,
IFS
eprintf
são fornecidos pelo POSIX, assim que deve funcionar na maioria POSIX-como conchas (especialmente Dash, que Ubuntu geralmente aliases comosh
).Pitão
Você deve usar o Python para isso? Você poderia. Este é o comando Python mais curto que consigo pensar nisso:
ou apenas Python 3 (e talvez mais legível?):
Eles devem funcionar em qualquer ambiente shell comum, desde que você possua Python.
fonte
Esta solução é mais simples que as soluções Java , C , go e awk :
Aqui está outra grande possibilidade:
Isso exigiria a instalação de algumas dependências:
fonte