Ich habe eine Textdatei mit nummerierten Einträgen:
1. foo
2. bar 100%
3. kittens
4. eat cake
5. unicorns
6. rainbows
und so weiter bis zu einer großen Anzahl. Nach einer leeren Zeile beginnt ein neuer Block bei 1.
Ich füge einen neuen Eintrag ein und ersetze beispielsweise 4. und muss alle nachfolgenden Einträge im Block neu nummerieren:
1. foo
2. bar 100%
3. kittens
4. sunshine <
5. eat cake
6. unicorns
7. rainbows
text-processing
Zanna
quelle
quelle
Antworten:
VIM-Lösungen
Es gibt zwei Lösungen: Eine erfolgt durch Automatisieren des CtrlaTastendrucks über eine Auswahl, die zweite durch Ausführen eines Musteraustauschs mit
submatch(0)+1
Über der Auswahl. Zuerst die Schlüsselautomatisierung.Beginnen Sie mit der Erstellung Ihrer Liste:
Fügen Sie einen Eintrag ein
Positionieren Sie den Cursor auf
4. sunshine
und aus dem Befehlsmodus. Drücken Sie shift+ vund dann shift+ g. Dies ist eine visuelle Auswahl bis zum Ende der Datei. Sie können den Cursor auch wie gewohnt an das Ende eines Blocks bewegen.Drücken Sie
:
, um den Befehlsmodus aufzurufen, und Sie sehen Folgendes ::'<,'>
. Geben Sie nun Folgendes ein:norm
Ctrl+ V Ctrl+AStrg-v und Strg-A ermöglichen es Ihnen, die "genaue" Taste einzugeben, damit sie in
^A
hervorgehoben wird. Dies bedeutet im Grundefor all lines selected, execute in normal mode keypress Ctrl-A
, und Strg-A erhöht standardmäßig die Zahl unter dem Cursor. Sie werden sehen, wie sich die Zahlen ändernLösung in Aktion:
Vor
Nach
Eine andere Möglichkeit wäre, alles aus der ersten wiederholten Nummer wie zuvor ( Shiftvdann G) auszuwählen und in den Befehlsmodus zu wechseln, um Folgendes auszuführen:
quelle
tmux
. Gibt es eine Möglichkeit, den gleichen Befehl wiectrl-A
vim über den vims-Befehlsmodus zu senden , sodass ich nicht Strg-A eingeben muss?Ctrl-a a
. Funktioniert auch an meinem Ende :)Sie können Ihren neuen Eintrag jederzeit mit einer
x. newentry
Syntax hinzufügen und anschließend alles neu nummerieren:-F .
: setzt das Feldtrennzeichen auf.
1-v OFS=.
: Gleiches gilt für das Ausgabefeldtrennzeichen (-F .
steht für-v FS=.
).{...}
: Keine Bedingung, daher wird der darin enthaltene Code{...}
für jede Zeile ausgeführtif (NF)
Wenn die Anzahl der Felder größer als 0 ist. MitFS
Sein.
bedeutet dies , dass die aktuelle Zeile mindestens eines enthält.
. Wir könnten es auch schaffen,if (length)
nach nicht leeren Zeilen zu suchen.$1 = ++n
: Setzen Sie das erste Feld auf ein Inkrementn
(zuerst 0, dann 1, dann 2 ...).else n = 0
: else (wenn NF == 0) setzt n auf 0 zurück.print
: Drucken Sie die (möglicherweise geänderte) Zeile.1 Die Syntax lautet
-F <extended-regular-expression>
jedoch, wenn<extended-regular-expression>
es sich um ein einzelnes Zeichen handelt, das nicht als regulärer Ausdruck (wobei.
ein beliebiges Zeichen bedeutet), sondern als dieses Zeichen.quelle
awk
Maximaler Overkill (und Komplexität! Und Fehler!) Können über das Perl-Modul Text :: Autoformat erzielt werden.
Die tatsächlichen Ergebnisse hängen von der Eingabe, der gewünschten Ausgabe, den übergebenen Optionen usw. ab.
quelle
Mit einfachen Shell-Tools kann dies folgendermaßen erfolgen - es kann sogar noch einfacher sein:
Ich erkläre von außen nach innen:
Erstellt Ausgabezeilen aus den Dateien als Spalten.
-d .
setzt das Trennzeichen auf.
, was hinter den neuen Zahlen endet.Startet
commandB
und präsentiert die Ausgabe so, als ob sie eine Datei enthält, aus der gelesen werden sollcommandA
, wobei ein Dateiname als Argument erwartet wird. (Siehe Befehlsersetzung.)Das zweite Argument
paste
,<(cut -d . -f 2- < new.list)
gibt die zweite Spalte unverändert, jede Zeile aus dem zweiten Bereich auf, die Mittel nach dem Starten.
.Das erste Argument von
paste
erstellt die neuen fortlaufenden Zeilennummern: Es zählt zuerst die Zeilen mit "wordcount lines":$(wc -l < new.list)
und verwendet diese Nummer, um eine Folge von Zahlen von 1 bis zur Anzahl mit zu erstellenseq 7
.quelle
.
- es wird davon ausgegangen, dass es die.
nach der Nummer gibt; Später hat.
eine Linie keine Auswirkung, da die Linie dann nur am ersten Trennzeichen vor Feld 2 (-f 2-
dh Feld 2 und folgende) geschnitten wird - und keine weiteren Trennzeichen berührt, die nicht zum Schneiden verwendet werden. Es behandelt sie als Port des Feldes. In Bezug auf die durch Zeilenumbrüche getrennten Abschnittecsplit
(auch voncoreutils
) scheint dies richtig zu sein; Bei leeren Zeilen grob aufteilen, oben beschrieben anwenden, Katzenergebnisse zusammen. Vielen Dank für den Hinweis!4., 4. 4.
Zeilen irregeführt . Mal sehen ...paste
undseq
noch mehr ... Ich kann es leicht in einem Editor machen, der die Zeilen zählt, aber ich möchte einen Weg, der nicht bricht, wenn Die Nummer, die ich einfügen möchte, ist NICHT die Zeilennummer> _ <Zahlen entfernen:
cut -d" " -f2- < list.txt > temp.txt
Zeile in temp.txt einfügen
Zahlen machen:
cat -n temp.txt| sed -e 's/^[ ]*\([0-9]*\)[ \t]*\(.*\)/\1. \2/' > list.txt
quelle