Editando arquivos com script de shell

3

Estou desenvolvendo um script e realizo cálculos que precisam ser incluídos em um arquivo de texto já preenchido. O formato das linhas do arquivo é:

1 20/10/16 12:00 take car in the garage joe's garage

Dentro do script, recebo um número de cálculos e esse número substituirá o primeiro número da linha. Por exemplo, o "calcular" retorna o valor 15, então o script deve acessar o arquivo em questão e alterar a linha em questão deve ter esta aparência:

15 20/10/16 12:00 take car in the garage joe's garage

O ponto é que eu não sei como realizar essa mudança. Pode ser em bash, awk, sed ou qualquer recurso disponível. Obrigado.

    
por D_Alves 14.10.2016 / 06:53

3 respostas

2

Que tal:

awk -v old=$oldNum -v new=$newNum \
'{if ($1==old) {$1=new; print} else {print}}' input.txt > output.txt

Tentei assim:

$ cat input.txt
2 19/10/16 15:30 some other line
1 20/10/16 12:00 take car in the garage joe's garage
3 17/10/16 5:30 another one

$ oldNum=2
$ newNum=15

Execute o comando awk e, em seguida:

$ cat output.txt
15 19/10/16 15:30 some other line
1 20/10/16 12:00 take car in the garage joe's garage
3 17/10/16 5:30 another one

É isso que você queria? Se você quiser que o resultado apareça no arquivo original, apenas mv do arquivo de saída com o novo nome input.txt , que deve substituir o arquivo de entrada (use um anti-slash \mv para evitar o aliasing do comando mv ).

NOTA: você provavelmente pode obter o mesmo resultado com instruções awk mais curtas, mas essa sintaxe torna-o mais legível. sed provavelmente pode fazer isso de uma maneira ainda mais concisa.

EDIT: Eu sei que isso funciona se você quiser alterar apenas 1 número dentro do seu arquivo. Se eu entendi seu problema corretamente, você deseja recalcular o número para a linha every e criar um arquivo com esses novos números. A melhor maneira de fazer isso seria incluir o cálculo do novo número de linha dentro do script awk , assim você não precisa criar um loop de shell, o que geralmente é uma má idéia desde ferramentas de chamada como awk , echo , sed ... repetidamente acabam sendo muito caras. Você poderia fazer algo assim:

if [ -f $PWD/output.txt ]; then 
    # Remove old output if present in current directory
    \rm -f $PWD/output.txt
fi

awk '{ ###calculation here, result store in newNum###; $1=newNum; print}' input.txt > output.txt

Por exemplo, se eu quiser trivialmente incrementar apenas um número de linha:

awk '{$1++; print}' input.txt > output.txt

Se você não puder (ou não ousar) incluir seu cálculo dentro de awk , você pode fazer um loop no arquivo, mas isso é muito desajeitado pelo que eu entendi sobre bash scripting:

if [ -f $PWD/output.txt ]; then 
    # Remove old output if present in current directory
    \rm -f $PWD/output.txt
fi

while read line
do
    newNum=###Calculation here for current line###
    echo $line | awk -v new=$newNum '$1=new' >> output.txt
done <input.txt
    
por 14.10.2016 / 10:31
1

tente isso ...

awk -v num="$variable" '{$1=num}1' input.txt
    
por 14.10.2016 / 07:35
0

Aqui está um pequeno script python que faz o que você quer. O uso é simples: forneça o arquivo, o número com o qual a linha começa e o número que você deseja ver

Demo:

    bash-4.3$ cat data.txt 
    2 19/10/16 15:30 some other line
    1 20/10/16 12:00 take car in the garage joe's garage
    3 17/10/16 5:30 another one
    bash-4.3$ python renumber.py data.txt 1 15
    ['renumber.py', 'data.txt', '1', '15']
    bash-4.3$ cat data.txt 
    2 19/10/16 15:30 some other line
    15 20/10/16 12:00 take car in the garage joe's garage
    3 17/10/16 5:30 another one

Código:

import sys
import os

print(sys.argv)

with open(sys.argv[1]) as inputfile:
    with open('/tmp/temp.text','w') as tempfile:
         for line in inputfile:
             old = line.strip().split()
             if old[0] == sys.argv[2]:
                old[0] = sys.argv[3] 
                line = ' '.join(old) + '\n' 
             tempfile.write(line)

os.rename('/tmp/temp.text',sys.argv[1])
    
por 14.10.2016 / 09:41