Domanda

Voglio usare lo spazio come delimitatore con il comando cut.

Quale sintassi posso usare per questo?

È stato utile?

Soluzione

cut -d ' ' -f 2

Dove 2 è il numero di campo del campo delimitato da spazi desiderato.

Altri suggerimenti

Di solito se usi lo spazio come delimitatore, vuoi trattare più spazi come uno, perché analizzi l'output di un comando allineando alcune colonne con gli spazi. (e la ricerca su Google per questo mi porta qui)

In questo caso un singolo comando cut non è sufficiente ed è necessario utilizzare:

tr -s ' ' | cut -d ' ' -f 2

O

awk '{print $2}'

Per integrare le risposte esistenti e utili; punta del cappello a Supporto QZ per avermi incoraggiato a pubblicare una risposta separata:

Due meccanismi distinti entrano in gioco qui:

  • (a) se cut stesso richiede che il delimitatore (spazio, in questo caso) passato all'opzione -d sia un argomento separato o se è accettabile aggiungerlo direttamente a -d ' '.

  • (b) come la shell generalmente analizza gli argomenti prima di passarli al comando da invocare.

(a) risponde a una citazione dalle Linee guida POSIX per le utility (sottolineatura mia)

  

Se la SINOSSI di un'utilità standard mostra un'opzione con un argomento opzione obbligatorio [...] un'applicazione conforme deve usare argomenti separati opzione e il relativo argomento opzione . Tuttavia , un'implementazione conforme deve anche consentire alle applicazioni di specificare l'opzione e l'argomento-opzione nella stessa stringa di argomenti senza caratteri intermedi .

In altre parole: in questo caso, poiché l'argomento opzione -d " " è obbligatorio , puoi scegliere se specificare il delimitatore come :

  • (E) OGNI: un argomento separato
  • (d) OPPURE: come valore direttamente allegato a -d \<space> # <space> used to represent an actual space for technical reasons .

Dopo aver scelto (s) o (d), è l'analisi di stringa-letterale della shell - (b) - che conta:

  • Con l'approccio (s) , tutti i seguenti moduli sono EQUIVALENTI:

    • -d' '
    • -d" "
    • "-d "
  • Con l'approccio (d) , tutti i seguenti moduli sono EQUIVALENTI:

    • '-d '
    • d\<space>
    • \
    • '...'
    • "..."

L'equivalenza è spiegata dall'elaborazione letterale stringa shell :

Tutte le soluzioni sopra riportate producono la esatta stessa stringa (in ciascun gruppo) quando $var le vede :

  • (s) : $(...) vede `...`, come proprio argomento, seguito da un separato argomento che contiene un carattere spaziale - senza virgolette o $(( ... )) prefisso !.

  • (d) : <=> vede <=> più un carattere spaziale - senza virgolette o <=> prefisso! - come parte dell'argomento stesso .

Il motivo per cui i moduli nei rispettivi gruppi sono in definitiva identici è duplice, basato su come la shell analizza string letterali :

  • La shell consente di specificare letteralmente come è tramite un meccanismo chiamato quoting , che può assumere diverse forme :
    • stringhe a virgoletta singola : i contenuti all'interno di <=> sono presi letteralmente e formano un singolo argomento
    • stringhe tra virgolette doppie : i contenuti all'interno di <=> formano anche un singolo argomento, ma sono soggetti a interpolazione (espande i riferimenti alle variabili come <=>, sostituzioni di comandi (<=> o <=>) o espansioni aritmetiche (<=>).
    • <=> - citazione di singoli caratteri : un <=> che precede un singolo carattere fa interpretare quel carattere come letterale.
  • La citazione è completata da rimozione virgolette , che significa che una volta che la shell ha analizzato una riga di comando, rimuove i caratteri di virgolette dagli argomenti (racchiudendo <=> o <=> o <=> istanze), quindi, ilil comando che viene invocato non vede mai i caratteri virgolette .

Puoi anche dire

cut -d\  -f 2

nota che ci sono due spazi dopo la barra rovesciata.

I ho appena scoperto che puoi anche usa "-d ":

cut "-d "

test

$ cat a
hello how are you
I am fine
$ cut "-d " -f2 a
how
am

scut , un'utilità simile (più intelligente ma più lenta I fatto) che può usare qualsiasi regex perl come token di rottura. L'interruzione dello spazio bianco è l'impostazione predefinita, ma puoi anche interrompere regex multi-carattere, regex alternative, ecc.

scut -f='6 2 8 7' < input.file  > output.file

in modo che il comando precedente interrompesse le colonne negli spazi bianchi ed estraesse le colonne (basate su 0) 6 2 8 7 in quell'ordine.

Non puoi farlo facilmente con cut se i dati hanno ad esempio più spazi. Ho trovato utile normalizzare l'input per un'elaborazione più semplice. Un trucco è usare sed per la normalizzazione come di seguito.

echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2  #bar

Ho una risposta (ammetto una risposta un po 'confusa) che coinvolge sed, espressioni regolari e gruppi di acquisizione:

  • \S* - prima parola
  • \s* - delimitatore
  • (\S*) - seconda parola - acquisita
  • .* - resto della linea

Come espressione \(, il gruppo di acquisizione deve essere sottoposto a escape, ovvero \) e \1.

<=> restituisce una copia del gruppo acquisito, ovvero la seconda parola.

$ echo "alpha beta gamma delta" | sed 's/\S*\s*\(\S*\).*/\1/'
beta

Quando guardi questa risposta, è un po 'confusa e, potresti pensare, perché preoccuparsi? Bene, spero che alcuni possano andare & Quot; Aha! & Quot; e utilizzerà questo modello per risolvere alcuni complessi problemi di estrazione del testo con una singola <=> espressione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top