Combine o início de uma linha com algo lá?

1

Eu quero combinar o começo das linhas onde a linha contém algo.

Comando em Perl / Sed

's/^.?/\section{}/g'

mas o problema aqui é que ele também substitui o primeiro caractere de sentenças.

Como você pode adicionar ao início das linhas algo para linhas não vazias?

    
por Léo Léopold Hertz 준영 15.06.2015 / 12:53

3 respostas

5
sed '/./s/^/\section{}/'

Anexará \section{} a todas as linhas que contiverem pelo menos um caractere válido .

sed '/^$/!s/^/\section{}/'

Anexará \section{} a todas as linhas não vazias (ou seja, linhas que contenham pelo menos um byte ).

sed 's/./\section{}&/'

Inseria \section{} antes do primeiro caractere válido em cada linha (que possui um caractere tão válido). ( & é substituído pela parte correspondente).

Essas distinções entre byte e caractere podem ser significativas se você estiver em uma localidade com vários bytes por caractere (como UTF-8, que tende a ser o norma hoje em dia), mas lidar com texto codificado em um conjunto de caracteres de byte único estendido.

Por exemplo:

$ locale charmap
UTF-8
$ echo Москва | iconv -t iso-8859-5 | sed 's/./\section{}&/' | iconv -f iso-8859-5
Москва

(quando codificado em iso-8859-5, nenhum dos valores de byte resultante de Москва forma um caractere válido em UTF-8, portanto /./ não corresponde a nada).

Como no seu caso, a codificação não seria uma preocupação, pois o texto que você inseriu é ASCII, você pode corrigir a localidade para C para evitar surpresas:

$ echo Москва | iconv -t iso-8859-5 | LC_ALL=C sed 's/./\section{}&/' | iconv -f iso-8859-5
\section{}Москва
    
por 15.06.2015 / 13:22
2

Você pode fazer isso em duas declarações com sed : a primeira para garantir que nenhuma linha vazia seja correspondida e a segunda para acrescentar no início:

sed '/^$/n;s/^/\section{}/'

Ou você pode fazer isso em uma declaração, capturando o que combina e adicionando ao seu substituto:

sed 's/^\(.\)/\section{}/'

Aqui, os parênteses \( e \) definem um grupo de captura referenciado pelo na parte de substituição da declaração.

Observe também que, para garantir que a linha não esteja vazia, é necessário remover a marca de interrogação ? após o ponto . . ? significa "0 ou 1", portanto, a linha vazia corresponderia ao tamanho 0.

    
por 15.06.2015 / 12:58
0

Use uma asserção de antecipação positiva com largura zero:

perl -pe 's/^(?=.)/\section{}/'

perlre diz:

(?=pattern) A zero-width positive look-ahead assertion. For example, /\w+(?=\t)/ matches a word followed by a tab, without including the tab in $&

Outra solução:

perl -lpe 's/^/\section{}/ if length'

Você deve chomp \n no final de uma linha antes da verificação do comprimento.

A opção -l faz isso por você.

-l[octnum] enables automatic line-ending processing. It has two separate effects. First, it automatically chomps $/ (the input record separator) when used with -n or -p. Second, it assigns $\ (the output record separator) to have the value of octnum so that any print statements will have that separator added back on. If octnum is omitted, sets $\ to the current value of $/

    
por 17.07.2015 / 01:27