Gibt es einen Befehl wie cat
in Linux, der eine bestimmte Anzahl von Zeichen aus einer Datei zurückgeben kann?
ich habe beispielsweise eine Textdatei wie:
Hello world
this is the second line
this is the third line
Und ich möchte etwas, das die ersten 5 Zeichen zurückgibt, was "Hallo" wäre.
vielen Dank
head
funktioniert auch:
head -c 100 file # returns the first 100 bytes in the file
..wird die ersten 100 Bytes extrahieren und zurückgeben.
Das Schönste an der Verwendung von head
ist, dass die Syntax für tail
übereinstimmt:
tail -c 100 file # returns the last 100 bytes in the file
Sie können dd verwenden, um beliebige Byte-Blöcke zu extrahieren.
Zum Beispiel,
dd skip=1234 count=5 bs=1
würde die Bytes 1235 bis 1239 von seiner Eingabe zu seiner Ausgabe kopieren und den Rest verwerfen.
Um nur die ersten fünf Bytes von der Standardeingabe zu erhalten, führen Sie Folgendes aus:
dd count=5 bs=1
Wenn Sie den Namen der Eingabedatei angeben möchten, hat dd altmodisches Argument-Parsing.
dd count=5 bs=1 if=filename
Beachten Sie auch, dass dd ausführlich bekannt gibt, was es getan hat.
dd count=5 bs=1 2>&-
oder
dd count=5 bs=1 2>/dev/null
Kopf :
head - gibt den ersten Teil der Dateien aus
kopf [MÖGLICHKEIT] ... [DATEI] ...
Drucken Sie die ersten 10 Zeilen jeder DATEI zur Standardausgabe. Stellen Sie bei mehr als einer DATEI jeweils einen Header mit Dateiname voran. Ohne FILE oder wenn FILE - ist, lesen Sie die Standardeingabe .
Erforderliche Argumente für lange Optionen sind auch für kurze Optionen obligatorisch .
-c. --Bytes=[-] N Die ersten N Bytes jeder Datei ausgeben. Mit dem führenden "-" werden alle bis auf die letzten N Bytes jeder Datei gedruckt
kopf oder Schwanz können es auch tun:
Kopf -c X
Gibt die ersten X-Bytes (nicht unbedingt Zeichen, wenn es sich um eine UTF-16-Datei handelt) der Datei aus. tail tut dasselbe, mit Ausnahme der letzten X-Bytes.
Dies (und der Schnitt) sind portabel.
head -Line_number file_name | tail -1 |cut -c Num_of_chars
dieses Skript gibt die genaue Anzahl der Zeichen aus der jeweiligen Zeile und Position an, z. B .:
head -5 tst.txt | tail -1 |cut -c 5-8
gibt die Zeichen in Zeile 5 und Zeichen 5 bis 8 von Zeile 5 an,
Hinweis : tail -1
wird verwendet, um die letzte vom Kopf angezeigte Zeile auszuwählen.
Ich weiß, die Antwort ist eine Antwort auf eine Frage, die vor 6 Jahren gestellt wurde ...
Aber ich habe ein paar Stunden nach etwas Ähnlichem gesucht und dann herausgefunden, dass: cut -c genau das tut, mit einem zusätzlichen Bonus, mit dem Sie auch einen Offset angeben können.
cut -c 1-5 kehrt zurück Hallo und cut -c 7-11 kehrt zurück world . Kein anderer Befehl nötig
sie können die Zeile auch herausgreifen und dann z. B. abschneiden:
grep 'text' Dateiname | Schneiden Sie -c 1-5
Obwohl dies vor Jahren beantwortet/akzeptiert wurde, ist die derzeit akzeptierte Antwort nur für 1-Byte-Zeichen wie iso-8859-1 oder für die Einzelbyte-Teilmengen von variablen Byte-Zeichensätzen (wie lateinische Zeichen) korrekt innerhalb UTF-8). Sogar die Verwendung von Mehrbyte-Spleißen würde nur für Kodierungen mit festem Multibyte wie UTF-16 funktionieren. Angesichts der Tatsache, dass UTF-8 nun auf dem besten Weg ist, ein universeller Standard zu sein, und wenn Sie diese Liste der Sprachen nach Anzahl der Muttersprachler und dieser Liste der Top 30 Sprachen nach einheitlicher/sekundärer Verwendung betrachten Es ist wichtig, auf ein einfaches zeichenfreundliches (nicht bytebasiertes) Byte-Byte-Verfahren hinzuweisen, das cut -c
und tr
/sed
mit Zeichenklassen verwendet.
Vergleichen Sie das Folgende, das aufgrund zweier häufiger lateinischer Fehler/Annahmen bezüglich der Ausgabe von Bytes vs. Zeichen doppelt fehlschlägt (einer ist head
vs. cut
, der andere ist [a-z][A-Z]
vs. [:upper:][:lower:]
):
$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$ head -c 1 | \
$ sed -e 's/[A-Z]/[a-z]/g'
[[unreadable binary mess, or nothing if the terminal filtered it]]
(Hinweis: Das funktionierte unter FreeBSD gut, aber sowohl cut
als auch tr
unter GNU/Linux haben in UTF-8 jedoch immer noch Griechisch verstümmelt):
$ printf 'Πού μπορώ να μάθω σανσκριτικά;\n' | \
$ cut -c 1 | \
$ tr '[:upper:]' '[:lower:]'
π
Eine andere, neuere Antwort hatte bereits "Cut" vorgeschlagen, jedoch nur wegen des Nebenproblems, dass mit ihm willkürliche Offsets angegeben werden können, und nicht wegen des direkt relevanten Charakters vs. Bytes-Problems.
Wenn Ihre cut
-c
nicht korrekt mit variablen Byte-Kodierungen behandelt, können Sie für "die ersten X
-Zeichen" (ersetzen Sie X
durch Ihre Nummer) Folgendes versuchen:
sed -E -e '1 s/^(.{X}).*$/\1/' -e q
- was jedoch auf die erste Zeile beschränkt isthead -n 1 | grep -E -o '^.{X}'
- der auf die erste Zeile beschränkt ist und zwei Befehle verkettetdd
- was bereits in anderen Antworten vorgeschlagen wurde, aber wirklich umständlich istsed
-Skript mit gleitendem Fensterpuffer zur Handhabung von Zeichen, die über mehrere Zeilen verteilt sind, aber das ist wahrscheinlich unhandlicher/fragiler als nur etwas wie dd
.Wenn Ihre tr
Zeichenklassen mit variablen Byte-Kodierungen nicht korrekt verarbeitet, können Sie Folgendes versuchen:
sed -E -e 's/[[:upper:]]/\L&/g
(GNU-spezifisch)Hier ist ein einfaches Skript, das mit dem hier genannten dd
-Ansatz abgeschlossen wird:
#!/usr/bin/env bash
function show_help()
{
IT="
extracts characters X to Y from stdin or FILE
usage: X Y {FILE}
e.g.
2 10 /tmp/it => extract chars 2-10 from /tmp/it
EOF
"
echo "$IT"
exit
}
if [ "$1" == "help" ]
then
show_help
fi
if [ -z "$1" ]
then
show_help
fi
FROM=$1
TO=$2
COUNT=`expr $TO - $FROM + 1`
if [ -z "$3" ]
then
dd skip=$FROM count=$COUNT bs=1 2>/dev/null
else
dd skip=$FROM count=$COUNT bs=1 if=$3 2>/dev/null
fi