Eu tenho as seguintes linhas em um arquivo:
Modified folders: html/project1/old/dev/vendor/symfony/yaml/Tests/bla.yml
Modified folders: html/port5/.DS_Store
Modified folders: html/trap/dev8/.DS_Store
Modified folders: html/bla3/test/appl/.DS_Store
Modified folders: html/bla4/pro1/app/bla/Api2.php
Modified folders: html/bla10/dev/appl/language/.DS_Store
Modified folders: html/bla11/dev/appl/language/abc.txt
Isso é basicamente saída de rsync
. Gostaria de listar todas as linhas do arquivo em até 3 locais de diretório, como
Modified folders: html/project1/old
Modified folders: html/port5
Modified folders: html/trap/dev8
Modified folders: html/bla3/test
Modified folders: html/bla4/pro1
Modified folders: html/bla10/dev
Modified folders: html/bla11/dev
Alguém pode me fornecer algum comando ou script de shell para fazer o mesmo?
command-line
scripts
text-processing
rsync
cut-command
john deo
fonte
fonte
>
caracteres no início das linhas e quebras de linha duplas ou se é sua tentativa de formatar o conteúdo com precisão.Respostas:
Talvez assim:
Ou você pode fazer a segunda parte com
cut
:Notas
-r
use EREs|old|new|
substituaold
pornew
[^/]*
qualquer número de caracteres que não sejam/
$
fim da linha/?
zero ou um/
(pattern)
salvepattern
para fazer referência mais tarde com\1
.*
qualquer número de caracteres|
tubo de revestimento (sem aspas) - passa a saída do comando do lado esquerdo para o comando do lado direitocut -d '/'
use/
como delimitador-f 1,2,3
imprima os três primeiros camposfonte
grep -Po '^.*?(/[^/]*){0,2}(?=/|$)'
, mas isso sofre o mesmo problema, e não consigo descobrir agora. Sinta-se livre para usá-lo, se isso lhe ajudar.O script a seguir fará (quase) o que você pede.
Ele lê todas as linhas de entrada, seleciona alguns valores (meus meios de regex), substitui a linha pelos valores selecionados e, finalmente, imprime a linha agora modificada (para STDOUT).
Resultado
Se escrevermos o regex em uma única linha:
então parece um pouco assustador, mas na verdade é bem simples. O operador básico é o operador de substituição
s///
do Perl.substituirá toda ocorrência de
foo
combar
.s
nos permite alterar o delimitador de/
para algo diferente. Eu usei um!
aqui, então também poderíamos escreverO
!
que não quer dizernot
que é apenas um caráter arbitrário aqui.sLfooLbarL;
funcionaria também. Fazemos isso porque, se usarmos o padrão/
, precisaremos escapar/
dos parâmetros (que são conhecidos como sintaxe do palito). Considere que queremos substituir o caminho/old/path
por/new/path
. Agora compare:Também podemos aplicar o
x
modificador ao arquivos///
. Permite um espaço em branco arbitrário (até novas linhas e comentários) no padrão (lado esquerdo) para melhorar a legibilidade. Agora o loop pode ser escrito como:O "script" completo também pode ser escrito como uma linha:
Atualizar
Acabei de perceber que a
Modified folders:
string também pode ser vista como um componente do caminho. Portanto, o padrão pode ser simplificado parafonte
uma breve explicação do dark regexp usado:
^...
eu começo da linha.*?
uma seq. de caracteres (mas apenas a quantidade necessária) para corresponder ao pré-caminho/.*?){0,2}
0, 1 ou 2 diretórios(?=/)
expressão antecipada - seguida por uma/
que não está incluídafonte
/
.