Suche…


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

Grundlegende Verwendung

Die typische Verwendung erfolgt bei CSV-Dateien, wobei jede Zeile aus Feldern besteht, die durch ein Trennzeichen getrennt sind, das durch die Option -d angegeben wird. Das Standardbegrenzer ist das TAB-Zeichen. Angenommen, Sie haben eine data.txt mit Zeilen wie

0 0 755 1482941948.8024
102 33 4755 1240562224.3205
1003 1 644 1219943831.2367

Dann

# extract the third space-delimited field
$ cut -d ' ' -f3 data.txt
755
4755
644

# extract the second dot-delimited field
$ cut -d. -f2 data.txt    
8024
3205
2367

# extract the character range from the 20th through the 25th character
$ cut -c20-25 data.txt 
948.80
056222    
943831

Wie üblich können zwischen einem Switch und seinem Parameter optionale Leerzeichen stehen: -d, -d ,

GNU- cut ermöglicht die Angabe einer Option --output-delimiter : (Ein unabhängiges Merkmal dieses Beispiels ist, dass ein Semikolon als Eingabebegrenzer mit --output-delimiter werden muss, um eine besondere Behandlung durch die Shell zu vermeiden.

$ cut --output-delimiter=, -d\; -f1,2 <<<"a;b;c;d"
a,b

Nur ein Trennzeichen

Sie können nicht mehr als ein Trennzeichen haben: Wenn Sie etwas wie -d ",;:" angeben, verwenden einige Implementierungen nur das erste Zeichen als Trennzeichen (in diesem Fall das Komma). Andere Implementierungen (z. B. GNU- cut ) geben den Wert an Ihnen eine Fehlermeldung.

$ cut -d ",;:" -f2 <<<"J.Smith,1 Main Road,cell:1234567890;land:4081234567"
cut: the delimiter must be a single character
Try `cut --help' for more information.

Wiederholte Trennzeichen werden als leere Felder interpretiert

$ cut -d, -f1,3 <<<"a,,b,c,d,e"
a,b

ist ziemlich offensichtlich, aber mit raumbegrenzten Zeichenketten ist es für einige weniger offensichtlich

$ cut -d ' ' -f1,3 <<<"a  b c d e"
a b

cut kann nicht wie in der Shell und anderen Programmen Argumente analysiert werden.

Kein Zitat

Es gibt keine Möglichkeit, den Begrenzer zu schützen. Tabellenkalkulationen und ähnliche CSV-Handhabungssoftware können in der Regel ein Anführungszeichen erkennen, mit dem Zeichenfolgen definiert werden können, die ein Trennzeichen enthalten. Mit dem cut kannst du nicht.

$ cut -d, -f3 <<<'John,Smith,"1, Main Street"'
"1

Extrahieren, nicht manipulieren

Sie können nur Teile von Zeilen extrahieren, keine Felder neu anordnen oder wiederholen.

$ cut -d, -f2,1 <<<'John,Smith,USA' ## Just like -f1,2
John,Smith
$ cut -d, -f2,2 <<<'John,Smith,USA' ## Just like -f2
Smith


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow