Substituir espaços em uma substring combinada por sublinhados

0

Sou novo no fórum, por favor, perdoe quaisquer erros sintáticos na minha pergunta.

Estou tentando substituir espaços por sublinhados apenas em uma substring correspondente. Eu imaginei que sed seria o melhor editor para isso, mas não consigo encontrar o código correto para fazer isso.

Exemplo de linha do arquivo1 abaixo:

Some text before pattern to match href="./Dynamic Directory name - Junk_files/irrelevant stuff after match">

Gostaria de mudar isso:

Some text before pattern to match href="./Dynamic_Directory_name_-_Junk_files/irrelevant stuff after match">

Eu achei que estava perto com esse cat file1 |sed '/\.\/.*. Junk_files/ { s/ /_/g; }' , mas tudo o que ele fez foi substituir todos os espaços na linha correspondente por sublinhados.

Qualquer ajuda com isso seria muito apreciada. Obrigado

    
por dparz 02.03.2016 / 11:52

4 respostas

1

Através do python,

$ echo 'href="./Dynamic Directory name - Junk_files/irrelevant stuff after match"' |
> python -c "import re;
> import sys;
> print re.sub(r'(?<=\./).*?(?=/)', lambda m: m.group().replace(' ', '_'), sys.stdin.read())
> "
href="./Dynamic_Directory_name_-_Junk_files/irrelevant stuff after match"

Através do perl,

$ echo 'href="./Dynamic Directory name - Junk_files/irrelevant stuff' | perl -pe '
> s/\s(?=(?:(?!\.\/).)*?\/)/_/g
> '
href="./Dynamic_Directory_name_-_Junk_files/irrelevant stuff
    
por Avinash Raj 02.03.2016 / 12:58
1

Tente isso, ele encontra o primeiro par de barras e remove todos os espaços entre!

 awk -F'/' '{for(i=2;i<=NF;i++)if(i==2)gsub(" ","_",$i);}1' OFS="/"

Exemplo

file='href="./Dynamic Directory name - Junk_files/irrelevant stuff after match">' 
echo $file | awk -F'/' '{for(i=2;i<=NF;i++)if(i==2)gsub(" ","_",$i);}1' OFS="/"
# Output: 
href="./Dynamic_Directory_name_-_Junk_files/irrelevant stuff after match">
    
por wittich 02.03.2016 / 12:00
0

É melhor usar um analisador de XML.

Se você insistir em usar sed ; assumindo que o padrão permaneça consistente:

sed -r 's#^([^/]+/[^ ]+) ([^ ]+) ([^ ]+) - ([^ ]+/)#___-_#' file.txt

Isso substituirá todos os espaços entre duas barras ( / ) por sublinhados ( _ ). Como a entrada contém / , usei # como o separador de padrão para sed .

Exemplo:

% sed -r 's#^([^/]+/[^ ]+) ([^ ]+) ([^ ]+) - ([^ ]+/)#___-_#' <<<'Some text before pattern to match href="./Dynamic Directory name - Junk_files/irrelevant stuff after match">'
Some text before pattern to match href="./Dynamic_Directory_name_-_Junk_files/irrelevant stuff after match">
    
por heemayl 02.03.2016 / 12:07
0

Isso é HTML e, a menos que você tenha um subconjunto de HTML bastante simples e bem definido no seu arquivo, analisar HTML usando expressões regulares é uma péssima ideia.

Este one-liner Perl funciona para substituir essa substring nesse contexto específico:

printf 'Some text before pattern to match href="./Dynamic Directory name - Junk_files/irrelevant stuff after match">\n' | perl -ne 'if(/(.*?")(.*\/)(.*)/){$x = $1; $y = $2; $z = $3; $y =~ s/ /_/g; print("$x$y$z")}'

Significado: ele substituirá apenas espaços com sublinhados na primeira subcadeia delimitada " e / . Mas é isso aí. Se você estiver analisando um documento complexo, não o use . Você poderia tornar o padrão mais rígido (por exemplo, você poderia usar /href=(.*?")(.*\/)(.*)/ e print("href=$x$y$z") ), mas isso ainda poderia falhar em qualquer ocorrência de /href=(.*?")(.*\/)(.*)/ .

A menos que você esteja analisando um subconjunto HTML muito bem definido e simples em seu arquivo e você está certo algo assim não falhará, apenas use um analisador HTML.

    
por kos 02.03.2016 / 13:06