com sed:
ls | grep txt | sed 's/.*/prefix&suffix/'
Eu encontrei um problema ao tentar escrever um script Bash. Quando grep
gera, retorna (geralmente) muitas linhas. Eu gostaria de prefixar e sufixar uma string para cada uma dessas linhas de saída.
Eu também gostaria de observar que estou canalizando ls
para grep
, como:
ls | grep
com sed
:
ls | grep pattern | sed -e 's/^/prefix/' -e 's/$/suffix/'
Mas note que isso sofre de problemas com nomes de arquivos com feeds de linha e todos os problemas de análise de ls
, o que geralmente é uma má ideia.
com perl
perl -e 'print "prefix".$_."suffix\n" for grep { m/somepattern/} glob "*"'
Nota - perl grep
pode pegar um padrão - como o comando grep
, mas você também pode fazer coisas como aplicar testes de arquivo.
Por exemplo
grep {-d} glob "*" #filters directories.
grep { (stat)[9] > time() - 60 } glob "*" #reads file mtime and compares.
Dentro de grep
, o iterador padrão $_
é definido como o valor do elemento atual, portanto você pode aplicar sed
/ grep
style regex ou executar uma variedade de tarefas com base em $_
.
Neste caso, o GNU find
permite que você faça tudo isso de uma só vez, eliminando os canais e analisando potencialmente os problemas de ls
:
find . -maxdepth 1 -name '[^.]*' \
-regextype posix-extended -regex "MYPATTERN" \
-printf 'SOMEPREFIX %f SOMESUFFIX\n'
( find
não é uma boa maneira de modificar arbitrariamente a saída de outros comandos, é claro!)
Algumas notas:
-maxdepth 1
e -name [^.]*
fazem a correspondência de nome funcionar da mesma forma que uma ls
(ou ls .
) simples. Você pode usar qualquer glob de shell, mas observe que "*" corresponderá a um "." Principal. em um nome † ao contrário de bash
, então [^.]*
significa qualquer coisa que não tenha um "". .*thing.*
em vez de apenas thing
-name
/ -regex
em vez de ambos (por exemplo, -regex "[^.]. MYPATTERN. " -printf
suporta muitas coisas , %n
é o sem adornos nome do arquivo ou diretório † (this can depend on your version of
find
though, check the "STANDARDS CONFORMANCE" section of your man page)
Como uma alternativa possível sem a necessidade de programas externos, bash
tem compgen
, o que, entre outras coisas, expande globs, equivalente a ls
sem opções:
compgen -P "someprefix>" -S "<somesuffix" -G "pattern"
Isso lida com nomes de arquivos com espaço em branco, incluindo novas linhas. compgen -G "*"
deve fornecer a mesma saída que um ls
simples (mas note que ls *
é uma coisa totalmente diferente). Você ainda precisará de grep
, e isso pode ou não resolver o problema, mas vale a pena mencionar.
sed
e find
são desafiadas se seu prefixo / sufixo incluir caracteres de chave de expressão regular ou se desejar passar uma variável de ambiente (em vez de um valor imediato), xargs
+ echo
pode ser mais apropriado aqui .
Com variável de ambiente:
ls | grep p | xargs -I % sh -c "echo $PATH/%"
Com um inline:
ls | grep p | xargs -I % sh -c "echo 'pwd'/%"
Tags bash grep shell-script