Substituindo o primeiro número de um arquivo pela sua metade [fechado]

2

Eu tenho uma série de arquivos que possuem dois números na primeira linha (ou seja, 170 1742) e, em seguida, várias outras linhas. Se eu quiser apenas substituir, em cada arquivo, o primeiro número da sua metade (ou seja, 85 1742), como eu faria isso no Unix?

    
por Damien Esquerre 05.06.2017 / 09:51

3 respostas

4

perl -pi -e 's|\d+|$&/2|e if $. == 1; close ARGV if eof' ./*.txt

Substituiria a primeira seqüência de dígitos decimais na primeira linha de cada arquivo txt não oculto no diretório atual, com a representação decimal canônica de metade do número correspondente (3 para 006, 3,5 para 007, por exemplo) .

Se o número for muito grande (como maior que 1e20), perl pode mudar para a notação de engenharia (5e + 19).

Obviamente, essa abordagem é válida apenas para números inteiros decimais. Quando aplicado a .1 , forneceria .5 em vez de 0.05 ; quando aplicado a 1.5, daria 0.5.5 em vez de 0.75 ; quando aplicado a 0x10 , daria 0x10 (somente 0 é reduzido pela metade) em vez de 8 ou 0x8 e assim por diante.

Se você quisesse manipular números decimais em qualquer notação (1, 010 (significando 10, não octal 8), -1.123, 2.23e-4, inf, infinito, NaN ...)), você precisaria adapte a expressão regular correspondente, como:

s{(\d*\.\d+|\d+\.?)(e[-+]?\d+)?|nan|inf(inity)?}{$&/2}ie

Ou faça uma suposição sobre onde o número está na linha, como se fosse a primeira sequência de caracteres sem espaçamento:

s{\S+}{$&/2}e
    
por 05.06.2017 / 11:09
3

Algo parecido com isto?

awk 'FNR==1{print $1/2,$2;next}1' ./*.txt #or /directory/* or just file.txt

Ou até mesmo

awk 'FNR==1{$1=$1/2}1' file1

Acima awk irá imprimir os resultados correspondentes em sua tela ou você pode redirecionar a saída modificada para um novo arquivo usando >newfile

Com o GNU awk, você pode aplicar alterações diretamente no arquivo original usando o gnu awk inplace opção:

awk -i inplace 'FNR==1{$1=$1/2}1' file1

Se o seu awk não suporta o local, você pode fazê-lo manualmente como

 awk 'FNR==1{$1=$1/2}1' file > newfile && mv newfile file

Isso é realmente o que o awk (e até mesmo o sed) no local de edição faz sob o capô.

    
por 05.06.2017 / 10:00
0
tempd=$(mktemp -d)
for f in ./*.csv
do
   < "$f" \
       sed -e '1y/\t-/ _/; 1!s/.*/[&]/' |
       dc -e '
       [q]sq
       [?z0=q pc z0=?]s? # macro "?" to print line
       ?r2/ n32anpc l?x  # 1st line div/2 the last stack elem print it+spc+2nd
      ' \
   > "$tempd/$f"
   mv "$tempd/$f" .
done
rm -r "$tempd"
    
por 05.06.2017 / 16:21

Tags