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, dd
wenn möglich. Der Grund dafür ist, dass ich bereits verwende, dd
um 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 hello
und kopiert das folgende Leerzeichen. Der dritte springt zum letzten Wort world
und kopiert alle Zeichen außer dem ersten.
Dies geschah mitGNUdd
AberBSDdd
sieht 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
Antwort3
Ich denke, das ist möglich, dd
aber 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 -c
Option 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 pack
und unpack
Funktionen 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,
$head
dies ist der Anfang der Zeichenfolge bis zum ersten Byte, das wir entfernen möchten,$skip
dies ist der Bereich der Bytes, die wir entfernen möchten, und$tail
dies ist der Rest der Zeichenfolge.unpack
Die Vorlage"A2 A5 A*"
teilt die Zeichenfolge wie oben erläutert in drei Teile.Mit
$skip
entfernen 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
x10
In der unpack
Vorlage bedeutet dies, dass die 10 Bytes in der Zeichenfolge übersprungen werden.