Ad esempio, dato:
USCAGoleta9311734.5021-120.1287855805
Voglio estrarre solo:
US
Ad esempio, dato:
USCAGoleta9311734.5021-120.1287855805
Voglio estrarre solo:
US
Risposte:
Probabilmente il metodo più efficiente, se stai usando la bashshell (e sembra che tu lo sia, in base ai tuoi commenti), è usare la variante della sottostringa dell'espansione dei parametri:
pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US
Saranno shorti primi due caratteri di long. Se longè più corto di due caratteri, shortsarà identico.
Questo metodo in-shell di solito è migliore se lo farai molto (come 50.000 volte per rapporto come hai menzionato) poiché non c'è alcun sovraccarico di creazione del processo. Tutte le soluzioni che utilizzano programmi esterni soffriranno di tale sovraccarico.
Se vuoi anche assicurarti una lunghezza minima , potresti riempirla prima con qualcosa del tipo:
pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.
Ciò garantirebbe che qualsiasi cosa di lunghezza inferiore a due caratteri fosse riempita sulla destra con punti (o qualcos'altro, semplicemente cambiando il carattere usato durante la creazione tmpstr). Non è chiaro se ne hai bisogno, ma ho pensato di inserirlo per completezza.
Detto questo, ci sono molti modi per farlo con programmi esterni (ad esempio se non hai a bashdisposizione), alcuni dei quali sono:
short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ($0, 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*/\1/')
I primi due ( cute head) sono identici per una stringa a riga singola: fondamentalmente entrambi restituiscono solo i primi due caratteri. Si differenziano per il fatto che cutti daranno i primi due caratteri di ogni riga e headti daranno i primi due caratteri dell'intero input
Il terzo utilizza la funzione di awksottostringa per estrarre i primi due caratteri e il quarto utilizza i sedgruppi di acquisizione (utilizzando ()e \1) per acquisire i primi due caratteri e sostituire l'intera riga con essi. Sono entrambi simili a cut: forniscono i primi due caratteri di ogni riga nell'input.
Niente di tutto ciò ha importanza se sei sicuro che il tuo input sia una singola riga, hanno tutti lo stesso effetto.
printf '%s'invece di echonel caso in cui ci siano caratteri strani nella stringa: stackoverflow.com/a/40423558/895245 Per l'ossessione POSIX: head -cnon è POSIX cut -ce non lo awk substrsono, sed \1non sono sicuro.
il modo più semplice è
${string:position:length}
Dove questo estrae la $lengthsottostringa da $stringa $position.
Questo è un builtin bash quindi awk o sed non è richiesto.
Hai ottenuto più risposte buone e mi piacerebbe andare con la Bash incorporato me stesso, ma dal momento che hai chiesto sede awke ( quasi ) nessun altro offerto soluzioni basate su di essi, vi questi offrono:
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'
e
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'
La awksi dovrebbe essere abbastanza ovvio, ma qui è una spiegazione del seduno:
substr($0,1,2).
Se sei dentro bash, puoi dire:
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
Questo potrebbe essere proprio quello di cui hai bisogno ...
Solo grep:
echo 'abcdef' | grep -Po "^.." # ab
-Popzione per renderlo più breve. Tutte le espressioni regolari capiranno quel modello.
Puoi usare printf:
$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US
Abbastanza tardi in effetti, ma eccolo qui
sed 's/.//3g'
O
awk NF=1 FPAT=..
O
perl -pe '$_=unpack a2'
Se vuoi usare lo scripting della shell e non fare affidamento su estensioni non posix (come i cosiddetti bashismi), puoi usare tecniche che non richiedono strumenti esterni di fork come grep, sed, cut, awk, ecc., Che poi rendere il tuo script meno efficiente. Forse l'efficienza e la portabilità posix non sono importanti nel tuo caso d'uso. Ma nel caso lo sia (o semplicemente come una buona abitudine), puoi usare il seguente metodo di opzione di espansione dei parametri per estrarre i primi due caratteri di una variabile di shell:
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
Utilizza l' espansione del parametro "prefisso più piccolo" per rimuovere i primi due caratteri (questa è la ${var#??}parte), quindi l' espansione del parametro "suffisso più piccolo" (la ${var%parte) per rimuovere la stringa di tutti i caratteri tranne i primi due dall'originale valore.
Questo metodo è stato precedentemente descritto in questa risposta alla domanda "Shell = Controlla se la variabile inizia con #". La risposta descrive anche un paio di metodi di espansione dei parametri simili che possono essere utilizzati in un contesto leggermente diverso da quello che si applica alla domanda originale qui.
Se il tuo sistema utilizza una shell diversa (non bash), ma il tuo sistema lo ha bash, puoi comunque utilizzare la manipolazione intrinseca delle stringhe bashinvocando bashcon una variabile:
strEcho='echo ${str:0:2}' # '${str:2}' if you want to skip the first two characters and keep the rest
bash -c "str=\"$strFull\";$strEcho;"
bashse non lo stai già utilizzando.
Solo per divertimento, ne aggiungerò alcune che, sebbene siano troppo complicate e inutili, non sono state menzionate:
head -c 2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
echo 'USCAGoleta9311734.5021-120.1287855805' | dd bs=2 count=1 status=none
sed -e 's/^\(.\{2\}\).*/\1/;' <( echo 'USCAGoleta9311734.5021-120.1287855805')
cut -c 1-2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
python -c "print(r'USCAGoleta9311734.5021-120.1287855805'[0:2])"
ruby -e 'puts "USCAGoleta9311734.5021-120.1287855805"[0..1]'
se mystring = USCAGoleta9311734.5021-120.1287855805
print substr(mystring,0,2)
ci stamperebbe
dove 0 è la posizione iniziale e 2 è il modo in cui leggere i caratteri
awk. Scusa, all'inizio non potevo dirlo.
È questo quello che cerchi?
my $string = 'USCAGoleta9311734.5021-120.1287855805';
my $first_two_chars = substr $string, 0, 2;
rif: substr
perl -e 'print substr $ARGV[0], 0, 2' 'USCAGoleta9311734.5021-120.1287855805'