sed 's/^\(.\{14\}\) /Silver/
s/^\(.\{49\}\).\{20\}/xxxxxxxxxxxxxxxxxxxxx/
' <infile >outfile
Isso, eu acho.
Eu tenho um arquivo de entrada de amostra como abaixo:
Apple Orange Gold Silver Spoon Apple Orange Gold
Apple
Apple Orange
Apple Orange
Mango Gold Silver Spoon Apple Orange
Eu preciso verificar se a 15ª a 20ª posição é Espaço e, em seguida, substituí-la por uma string Silver
. Também preciso substituir completamente o conteúdo da 50ª para a 70ª posição com xxxxxxxxxxxxxxxxxxxxx
Dependendo de como linhas menores devem ser manipuladas (veja meu comentário acima), aqui está uma sed
solution:
sed -e '/^.\{14\} \{6\}/s/^\(.\{14\}\) \{6\}/Silver/' \
-e '/^.\{49\}./s/^\(.\{49\}\)\(.\{1,21\}\)\?\(.*\)\?/xxxxxxxxxxxxxxxxxxxxx/'
e muito melhor legível (e menos propenso a erros) GNU awk
version:
awk '
BEGIN { FIELDWIDTHS = "14 6 29 21 999" ; OFS = "" }
$2 == " " { $2 = "Silver" }
$4 != "" { $4 = "xxxxxxxxxxxxxxxxxxxxx" }
{ print }
'
Explicação:
1.) sed: O comando sed
é construído por duas substituições independentes, a primeira lida com a caixa "Prata" e a segunda com a "xxx ...". As substituições sed
são da forma:
/pattern/s/pattern2/replacement/
A respectiva substituição é executada se o primeiro padrão corresponder e, para essas linhas, o segundo padrão é substituído pela expressão de substituição. Os detalhes são as expressões codificadas sed
típicas:
.
- um caractere arbitrário
\{14\}
- uma repetição da subexpressão precedente (aqui 14 vezes)
\(expr\)
- uma subexpressão que pode ser referenciada na string de substituição por ,
, etc., onde o número real é definido pela n'ésima expressão parêntesis
\?
- especifica que a subexpressão precedente é uma parte opcional
2.) awk: O programa awk
executa a seção BEGIN
uma vez, e as seções subseqüentes para cada linha do arquivo de dados, e a respectiva ação right {...}
only se a condição da mão esquerda for verdadeira.
FIELDWIDTHS
- especifica a largura dos campos de dados nas linhas de entrada, para que cada campo possa ser endereçado por $i
(para algum campo i)
OFS=""
- uma string vazia; os campos de saída não devem ter nenhuma separação adicional
$2 == " "
- se o segundo campo (de acordo com a especificação FIELDWIDTHS
) contiver seis espaços em branco, substitua-o pela string especificada
$4 != ""
- se o quarto campo contiver dados, substitua-o pela string "xxx ..."
{ print }
- uma impressão incondicional da linha atual, que foi modificada por uma ou ambas as ações anteriores ou mostra a linha não modificada de outra forma
Supondo que linhas contendo menos de 21 caracteres (para a primeira substituição) e que linhas contendo menos de 70 caracteres (para a segunda substituição) devem ser descartadas, usando Perl:
< inputfile perl -pe 's/^(.{14}) {6}/$1Silver/; s/^(.{49}).{21}/$1xxxxxxxxxxxxxxxxxxxxx/' > outputfile
Supondo que linhas contendo menos de 21 caracteres (para a primeira substituição) e que linhas contendo menos de 70 caracteres (para a segunda substituição) devem ser preenchidas com espaços primeiro, usando awk
+ Perl:
< inputfile awk '{printf "%-70s\n", $0}' | perl -pe 's/^(.{14}) {6}/$1Silver/; s/^(.{49}).{21}/$1xxxxxxxxxxxxxxxxxxxxx/' > outputfile
Resumo do comando # 1 :
< inputfile
: redireciona o conteúdo de inputfile
para perl
' stdin
-p
: força o Perl a imprimir as linhas -e
: força o Perl a ler uma linha de programa dos argumentos > outputfile
: redireciona o conteúdo de perl
stdout
para outputfile
Divisão do comando # 2 :
< inputfile
in awk
: redireciona o conteúdo de inputfile
para awk
' stdin
{printf "%-70s", $0}
: preenche cada linha com espaços até que o número de caracteres na linha seja 70 |
: pipes awk
stdout
to perl
stdin
-p
: força o Perl a imprimir as linhas -e
: força o Perl a ler uma linha de programa dos argumentos > outputfile
: redireciona o conteúdo de perl
stdout
para outputfile
Repartição da substituição # 1 :
s
: afirma para executar uma substituição /
: inicia o padrão de pesquisa ^
: corresponde ao início da linha (
: inicia o grupo de captura .{14}
: corresponde a 14 ocorrências de qualquer caractere )
: pára o grupo de captura {6}
: corresponde a 6 ocorrências de um caractere
/
: interrompe o padrão de pesquisa / inicia o padrão de substituição $1
: substitui pelo grupo capturado Silver
: adiciona uma Silver
string /
: interrompe o padrão de substituição Divisão da substituição # 2 :
s
: afirma para executar uma substituição /
: inicia o padrão de pesquisa ^
: corresponde ao início da linha (
: inicia o grupo de captura .{49}
: corresponde a 49 ocorrências de qualquer caractere )
: pára o grupo de captura .{21}
: corresponde a 21 ocorrências de qualquer caractere /
: interrompe o padrão de pesquisa / inicia o padrão de substituição $1
: substitui pelo grupo capturado xxxxxxxxxxxxxxxxxxxxx
: adiciona uma xxxxxxxxxxxxxxxxxxxxx
string /
: interrompe o padrão de substituição Exemplo de saída:
:~/tmp$ cat inputfile
Apple Orange Gold Silver Spoon Apple Orange Gold
Apple
Apple Orange
Apple Orange
Mango Gold Silver Spoon Apple Orange
~/tmp$ < inputfile perl -pe 's/^(.{14}) {6}/$1Silver/; s/^(.{49}).{21}/$1xxxxxxxxxxxxxxxxxxxxx/'
Apple OrangeSilverGold Silver Spoon Apple Oxxxxxxxxxxxxxxxxxxxxxld
Apple
Apple Orange
Apple OrangeSilver
Mango SilverGold Silver Spoon Apple Orange
~/tmp$ < inputfile awk '{printf "%-70s\n", $0}' | perl -pe 's/^(.{14}) {6}/$1Silver/; s/^(.{49}).{21}/$1xxxxxxxxxxxxxxxxxxxxx/'
Apple OrangeSilverGold Silver Spoon Apple Oxxxxxxxxxxxxxxxxxxxxxld
Apple Silver xxxxxxxxxxxxxxxxxxxxx
Apple OrangeSilver xxxxxxxxxxxxxxxxxxxxx
Apple OrangeSilver xxxxxxxxxxxxxxxxxxxxx
Mango SilverGold Silver Spoon Apple Oxxxxxxxxxxxxxxxxxxxxx
~/tmp$
Tags text-processing awk sed