Looking for bash Keywords? Try Ask4Keywords

BashDer Befehl zum Ausschneiden


Einführung

Der Befehl cut ist eine schnelle Methode zum Extrahieren von Teilen von Textzeilen. Es gehört zu den ältesten Unix-Befehlen. Die beliebtesten Implementierungen sind die GNU-Version unter Linux und die FreeBSD-Version unter MacOS. Jede Unix-Variante hat jedoch ihre eigene. Siehe unten für Unterschiede. Die Eingabezeilen werden entweder aus stdin oder aus Dateien gelesen, die als Argumente in der Befehlszeile aufgeführt sind.

Syntax

  • schneiden -f1,3 # Extrakt ersten und dritten getabulatortrennte Feld (von stdin)

  • cut -f1-3 # Auszug aus dem ersten bis dritten Feld (Enden eingeschlossen)

  • cut -f-3 # -3 wird als 1-3 interpretiert

  • cut -f2- # 2- wird vom zweiten bis zum letzten interpretiert

  • Schneiden Sie -c1-5,10 # aus stdin die Zeichen an den Positionen 1,2,3,4,5,10 aus

  • cut -s -f1 # unterdrückt Zeilen, die keine Trennzeichen enthalten

  • cut --complement -f3 # (nur GNU-Cut) extrahiert alle Felder außer dem dritten

Parameter

Parameter Einzelheiten
-f, --fields Feldbasierte Auswahl
-d, --delimiter Trennzeichen für feldbasierte Auswahl
-c, --Zeichen Zeichenbasierte Auswahl, Trennzeichen ignoriert oder Fehler
-s, - nur begrenzt Zeilen ohne Trennzeichen unterdrücken (sonst wie gedruckt)
--ergänzen Invertierte Auswahl (alle außer den angegebenen Feldern / Zeichen extrahieren)
- Ausgabenbegrenzer Geben Sie an, wann es sich vom Eingangsbegrenzer unterscheiden muss

Bemerkungen

1. Syntaxunterschiede

Lange Optionen in der obigen Tabelle werden nur von der GNU-Version unterstützt.

2. Kein Charakter wird speziell behandelt

Der FreeBSD- cut (der zum Beispiel mit MacOS --complement ) verfügt nicht über den Schalter --complement Zeichenbereichen kann stattdessen der Befehl colrm verwendet werden:

  $ cut --complement -c3-5 <<<"123456789"
  126789

  $ colrm 3 5 <<<"123456789"
  126789

Es gibt jedoch einen großen Unterschied, da TAB-Zeichen (ASCII 9) in colrm bis zum nächsten Vielfachen von acht als reelle colrm und als (-1) breite colrm (ASCII 8) behandelt werden. Im Gegensatz dazu behandelt cut alle Zeichen als eine Spalte.

  $ colrm  3 8 <<<$'12\tABCDEF' # Input string has an embedded TAB
  12ABCDEF

  $ cut --complement -c3-8 <<<$'12\tABCDEF'
  12F

3. (Noch immer keine) Internationalisierung

Als der cut entworfen wurde, waren alle Zeichen ein Byte lang und die Internationalisierung war kein Problem. Als Schreibsysteme mit breiteren Zeichen populär wurden, bestand die von POSIX angenommene Lösung darin, zwischen dem alten -c Schalter zu wechseln, der seine Bedeutung für die Auswahl von Zeichen beibehalten sollte , unabhängig davon, wie viele Bytes breit sind, und einen neuen Schalter -b einzuführen, der sollte select bytes, unabhängig von der aktuellen Zeichenkodierung. In den meisten gängigen Implementierungen wurde -b eingeführt und funktioniert, aber -c funktioniert immer noch genauso wie -b und nicht wie es sollte. Zum Beispiel mit GNU- cut :

Es scheint, dass der Spam-Filter von SE schwarze Texte mit isolierten Kanji-Zeichen in die schwarze Liste einfügt. Ich konnte diese Einschränkung nicht überwinden, daher sind die folgenden Beispiele weniger ausdrucksvoll als sie sein könnten.

  # In an encoding where each character in the input string is three bytes wide,
  # Selecting bytes 1-6 yields the first two characters (correct)
  $ LC_ALL=ja_JP.UTF-8 cut -b1-6 kanji.utf-8.txt
  ...first two characters of each line...
  

  # Selecting all three characters with the -c switch doesn’t work.
  # It behaves like -b, contrary to documentation.
  $ LC_ALL=ja_JP.UTF-8 cut -c1-3 kanji.utf-8.txt
  ...first character of each line...

  # In this case, an illegal UTF-8 string is produced.
  # The -n switch would prevent this, if implemented.
  $ LC_ALL=ja_JP.UTF-8 cut -n -c2 kanji.utf-8.txt
  ...second byte, which is an illegal UTF-8 sequence...

Wenn sich Ihre Zeichen außerhalb des ASCII-Bereichs befinden und Sie cut möchten, sollten Sie immer die Zeichenbreite in Ihrer Kodierung -b und -b entsprechend verwenden. Wenn -c beginnt, wie dokumentiert zu arbeiten, müssen Sie Ihre Skripts nicht ändern.

4. Geschwindigkeitsvergleiche

Die Grenzen von cut haben Zweifel an der Nützlichkeit. In der Tat kann dieselbe Funktionalität durch leistungsfähigere, populärere Dienstprogramme erreicht werden. Der Vorteil von cut ist jedoch seine Leistung . Nachfolgend finden Sie einige Geschwindigkeitsvergleiche. test.txt hat drei Millionen Zeilen mit jeweils fünf durch Leerzeichen getrennten Feldern. Für den awk Test wurde mawk verwendet, weil es schneller als GNU awk . Die Hülle selbst (letzte Zeile) ist bei weitem die schlechteste Leistung. Die angegebenen Zeiten (in Sekunden), was die time Befehl als Echtzeit gibt.

(Nur um Missverständnisse zu vermeiden: Alle getesteten Befehle gaben dieselbe Ausgabe mit der angegebenen Eingabe aus, sind jedoch natürlich nicht gleichwertig und würden in verschiedenen Situationen unterschiedliche Ausgaben ergeben, insbesondere wenn die Felder durch eine variable Anzahl von Leerzeichen begrenzt sind.

Befehl Zeit
cut -d ' ' -f1,2 test.txt 1,138s
awk '{print $1 $2}' test.txt 1.688s
join -a1 -o1.1,1.2 test.txt /dev/null 1,767 s
perl -lane 'print "@F[1,2]"' test.txt 11.390s
grep -o '^\([^ ]*\) \([^ ]*\)' test.txt 22,925s
sed -e 's/^\([^ ]*\) \([^ ]*\).*$/\1 \2/' test.txt 52.122s
while read ab _; do echo $a $b; done <test.txt 55,582 s

5. Referenzseiten

Der Befehl zum Ausschneiden Verwandte Beispiele