Wie fügt man an der angegebenen Stelle ein Komma ein?

Wie fügt man an der angegebenen Stelle ein Komma ein?

Ich habe eine über 100 MB große Textdatei, deren Zeilen jeweils die gleiche Anzahl Spalten aufweisen:

Column No.: 0 1 2 3 4 5 6
            d x c c s b c
            .............

Ich möchte ,an bestimmten Stellen hinzufügen. Zum Beispiel:location = 2, 3, 5

Die gewünschte Ausgabe wäre:

Column No.:  0 1 2  3  4 5  6
             d x c, c, s b, c
             .............

Die Standortdatei wäre eineTextodercsvDatei

2
3
5

Die Textdatei muss Trennzeichen enthalten.

Aktualisieren:

Beispieldaten

Bildbeschreibung hier eingeben

  • Hinweis: Die Zeilenumbrüche sind dort, wo ich Trennzeichen einfügen möchte
  • Die Spaltennummer ist der Byte-Offset vom Zeilenanfang

Antwort1

Verwenden Sie Sed.

Beachten Sie, dass Sie nicht 0 indizierte Positionen verwenden, sondern bei 1 beginnen. Daher habe ich die von Ihnen angegebenen Zahlen erhöht.

Außerdem müssen Sie von hinten nach vorne gehen, da sich die Spaltenpositionen ändern, sobald Sie die erste Änderung vornehmen. Verwenden Sie Sed also folgendermaßen:

sed 's/./&,/6;s/./&,/4;s/./&,/3'

Beispiel:

$ echo dxccsbc
dxccsbc
$ echo dxccsbc | sed 's/./&,/6;s/./&,/4;s/./&,/3'
dxc,c,sb,c
$ 

  • Der sBefehl in Sed dient der Ersetzung.
  • Das Muster .passt zu jedem einzelnen Zeichen.
  • Das &im Ersetzungstext bedeutet „der Text, der übereinstimmte“ und das Komma ist ein wörtliches Komma.
  • Die numerische Flagge nach dem letzten /bedeutet, dass die Ersetzung nur beim „n-ten“ Treffer in der Zeile durchgeführt wird.

Wenn du sein willstWirklichSchick, verwenden Sie die Bash-Klammererweiterung, um die Sed-Befehle zu erstellen:

$ echo dxccsbc | sed '-es/./&,/'{6,4,3}
dxc,c,sb,c

Aber das ist nur das Tüpfelchen auf dem i und wahrscheinlich verwirrend, sofern Sie nicht sowohl Sed als auch Bash gut verstehen. :)


Wenn Sie die Liste der Positionen aus einer separaten Datei abrufen möchten(wie Sie in Ihrer Frage tatsächlich zeigen), können Sie dies folgendermaßen tun:

sed -f <(sort -rn positionsfile | sed -n 's:^[1-9][0-9]*$:s/./\&,/&:p') file

Beachten Sie, dass dies Bash-spezifisch ist, da es eine Prozesssubstitutionssyntax verwendet, die nicht POSIX ist. Beachten Sie auch, dass ich dies ziemlich robust gemacht habe, da alles andere als tatsächlichZahlenin der Positionsdatei (die nicht mit 0 beginnen) werden verworfen.

Testergebnisse:

$ cat file 
abcdefg
ABCDEFG
abcdelaksjdflkjsdflli
sdlfihsdlfkj
$ cat positionsfile 
2
15
5
7something
01
not a number
$ sed -f <(sort -rn positionsfile | sed -n 's:^[1-9][0-9]*$:s/./\&,/&:p') file
ab,cde,fg
AB,CDE,FG
ab,cde,laksjdflkj,sdflli
sd,lfi,hsdlfkj
$ 

Antwort2

Mit perl:

#!/usr/bin/env perl

my @pos;

while (<>)
    { push @pos, 1 + int; }
continue
    { last if eof; }

@pos = sort { $b cmp $a } @pos;

while (<>) {
    for my $k (@pos)
        { s/^.{$k}\K/,/; }
    print;
}

Führen Sie es wie folgt aus:

script.pl positions.txt file.txt

verwandte Informationen