dd entfernt Bytebereich

dd entfernt Bytebereich

Angesichts dieser Datei

$ cat hello.txt
hello doge world

Ich möchte einen Bytebereich entfernen, um das hier zu erhalten

$ cat hello.txt
heorld

Ich würde dies gerne mit tun, ddwenn möglich. Der Grund dafür ist, dass ich bereits verwende, ddum Bytes auf diese Weise zu überschreiben

printf '\x5E' | dd conv=notrunc of=hello.txt bs=1 seek=$((0xE))

Ich bevorzuge das Zurückschreiben in dieselbe Datei, aber eine andere Ausgabedatei wäre auch in Ordnung.

Antwort1

Es geht darum, Blockgröße, Anzahl und Überspringen anzugeben:

$ cat hello.txt
hello doge world
$ { dd bs=1 count=2 ; dd skip=3 bs=1 count=1 ; dd skip=6 bs=1 ; } <hello.txt 2>/dev/null
he orld

Oben werden drei Aufrufe von verwendet dd. Der erste ruft die ersten beiden Zeichen ab he. Der zweite springt zum Ende von hellound kopiert das folgende Leerzeichen. Der dritte springt zum letzten Wort worldund kopiert alle Zeichen außer dem ersten.

Dies geschah mitGNUddAberBSDddsieht aus, als ob es auch funktionieren sollte.

Antwort2

# copy the end piece into correct position
dd bs=1 seek=2 skip=12 conv=notrunc if=hello.txt of=hello.txt

# truncate
dd bs=1 seek=6 if=/dev/null of=hello.txt

Mark hat recht

Antwort3

Ich denke, das ist möglich, ddaber das ist so, als würde man mit einem Panzer eine Fliege töten. Warum nicht

$ printf "%s %s\n" $(head -c 2 hello.txt) $(tail -c 5 hello.txt )
he orld

Die -cOption bedeutet (für head):

   -c, --bytes=[-]K
          print the first K bytes of each  file;  with  the  leading  '-',
          print all but the last K bytes of each file

und für tail:

   -c, --bytes=K
          output the last K bytes; alternatively,  use  -c  +K  to  output
          bytes starting with the Kth of each file

Um den Bytebereich zu entfernen,NZuXinklusive, würden Sie laufen

( head -c n-1; head -c -x-1)  )

So entfernen Sie beispielsweise das 4. bis 12. Byte:

$ (head -c 3 hello.txt; tail -c +11 hello.txt )
hel world

Antwort4

Perl packund unpackFunktionen sind gut im Umgang mit Strings fester Breite. Wenn Sie verwenden möchten Perl, versuchen Sie Folgendes:

$ perl -le '
    ($head,$skip,$tail) = unpack("A2 A5 A*", "hello world");
    ($space) = $skip =~ m/(\s+)/;
    print $head.$space.$tail;
'
he orld

Erläuterung

  • Wir werden die Zeichenfolge in drei Teile aufteilen, $headdies ist der Anfang der Zeichenfolge bis zum ersten Byte, das wir entfernen möchten, $skipdies ist der Bereich der Bytes, die wir entfernen möchten, und $taildies ist der Rest der Zeichenfolge.

  • unpackDie Vorlage "A2 A5 A*"teilt die Zeichenfolge wie oben erläutert in drei Teile.

  • Mit $skipentfernen wir alle darin enthaltenen Leerzeichen und speichern sie in $space.

  • Drucken Sie die Verkettung der drei Teile, um die gewünschte Ausgabe zu erhalten.

Aktualisiert

Da Sie den Platz nicht sparen möchten, scheint die Lösung einfacher zu sein:

$ perl -le 'print unpack("A2 x5 A*","hello world")'
heorld

Mit aktualisierter Zeichenfolge:

$ perl -le 'print unpack("A2 x10 A*","hello doge world")'
heorld

x10In der unpackVorlage bedeutet dies, dass die 10 Bytes in der Zeichenfolge übersprungen werden.

verwandte Informationen