Bearbeiten von Dateien mit Shell-Skript

Bearbeiten von Dateien mit Shell-Skript

Ich entwickle ein Skript, das Berechnungen durchführt, die in eine bereits ausgefüllte Textdatei aufgenommen werden müssen. Das Format der Dateizeilen ist:

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

Im Skript erhalte ich eine Zahl aus den Berechnungen, und diese Zahl ersetzt die erste Zahl der Zeile. Wenn beispielsweise „calculate“ den Wert 15 zurückgibt, muss das Skript auf die betreffende Datei zugreifen und die betreffende Zeile ändern. Sie sollte folgendermaßen aussehen:

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

Der Punkt ist, dass ich nicht weiß, wie ich diese Änderung vornehmen soll. Das kann in Bash, Awk, Sed oder jeder anderen verfügbaren Ressource geschehen. Vielen Dank.

Antwort1

Wie wäre es mit:

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

Habe es so probiert:

$ 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

Führen Sie den awk-Befehl aus und gehen Sie dann wie folgt vor:

$ 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

Ist es das, was Sie wollten? Wenn Sie möchten, dass Ihr Ergebnis in der Originaldatei angezeigt wird, reicht mvdie Ausgabedatei mit dem neuen Namen aus. input.txtDiese sollte die Eingabedatei überschreiben (verwenden Sie einen Anti-Schrägstrich, \mvum Aliasing des mvBefehls zu vermeiden).

HINWEIS: Sie können wahrscheinlich dasselbe Ergebnis mit kürzeren awk-Anweisungen erzielen, diese Syntax macht es jedoch lesbarer. sedSie können es wahrscheinlich auf eine noch prägnantere Weise erreichen.


EDIT: Mir ist klar, dass dies funktioniert, wenn Sie nur eine Zahl in Ihrer Datei ändern möchten. Wenn ich Ihr Problem richtig verstehe, möchten Sie die Zahl fürjedenZeile und erstellen Sie eine Datei mit diesen neuen Nummern. Der optimale Weg, dies zu tun, wäre, Ihre Berechnung der neuen Zeilennummer einzuschließeninnendas awkSkript, auf diese Weise müssen Sie keine Shell-Schleife erstellen, was im Allgemeinen keine gute Idee ist, da das wiederholte Aufrufen von Tools wie awk, echo, sed... sehr kostspielig ist. Sie könnten so etwas tun:

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

Wenn ich beispielsweise einfach jede Zeilennummer um eins erhöhen möchte:

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

Wenn Sie Ihre Berechnung nicht darin einschließen können (oder sich nicht trauen) awk, können Sie eine Schleife über die Datei ausführen, aber das ist, soweit ich bashSkripting verstehe, ziemlich umständlich:

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

Antwort2

Versuche dies..

awk -v num="$variable" '{$1=num}1' input.txt

Antwort3

Hier ist ein kurzes Python-Skript, das genau das tut, was Sie wollen. Die Verwendung ist einfach: Geben Sie ihm die Datei, die Nummer, mit der die Zeile beginnt, und die Nummer, die Sie stattdessen sehen möchten.

Demo:

    bash-4.3$ Katze Daten.txt
    2 19/10/16 15:30 eine andere Zeile
    1 20/10/16 12:00 Auto in die Garage bringen Joes Garage
    3 17/10/16 5:30 noch einer
    bash-4.3$ python renumber.py data.txt 1 15
    ['renumber.py', 'data.txt', '1', '15']
    bash-4.3$ Katze Daten.txt
    2 19/10/16 15:30 eine andere Zeile
    15 20/10/16 12:00 Auto in die Garage bringen Joes Garage
    3 17/10/16 5:30 noch einer

Code:

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])

verwandte Informationen