it-swarm.com.de

Wie extrahiere ich die ersten beiden Zeichen einer Zeichenfolge in Shell-Skripten?

Zum Beispiel gegeben:

USCAGoleta9311734.5021-120.1287855805

Ich möchte nur extrahieren:

US
100
Greg

Wenn Sie die bash -Shell verwenden (und Sie scheinen es zu sein, basierend auf Ihren Kommentaren), ist es wahrscheinlich die effizienteste Methode, die Unterzeichenfolgenvariante der Parametererweiterung zu verwenden:

pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US

Dies setzt short auf die ersten beiden Zeichen von long. Wenn long kürzer als zwei Zeichen ist, ist short identisch damit.

Diese In-Shell-Methode ist in der Regel besser, wenn Sie sie häufig ausführen (wie Sie bereits erwähnt haben, etwa 50.000 Mal pro Bericht), da kein Aufwand für die Erstellung von Prozessen entsteht. Alle Lösungen, die externe Programme verwenden, leiden unter diesem Overhead.

Wenn Sie auch eine minimale Länge sicherstellen möchten, können Sie diese vorher mit etwas anderem auffüllen:

pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.

Dies würde sicherstellen, dass weniger als zwei Zeichen rechts mit Punkten aufgefüllt werden (oder etwas anderes, indem einfach das Zeichen geändert wird, das beim Erstellen von tmpstr verwendet wird). Es ist nicht klar, dass Sie das brauchen, aber ich dachte, ich würde es der Vollständigkeit halber einsetzen.


Allerdings gibt es eine Reihe von Möglichkeiten, dies mit externen Programmen zu tun (zum Beispiel, wenn Ihnen bash nicht zur Verfügung steht). Einige davon sind:

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/')

Die ersten beiden (cut und head) sind für eine einzeilige Zeichenfolge identisch - im Grunde geben beide nur die ersten beiden Zeichen zurück. Sie unterscheiden sich darin, dass cut die ersten beiden Zeichen jeder Zeile und head die ersten beiden Zeichen der gesamten Eingabe enthält

Die dritte verwendet die Unterzeichenfolgenfunktion awk, um die ersten beiden Zeichen zu extrahieren, und die vierte verwendet sed Erfassungsgruppen (unter Verwendung von () und \1), um die ersten beiden Zeichen zu erfassen und die gesamte Zeile durch diese zu ersetzen. Sie sind beide cut ähnlich - sie liefern die ersten beiden Zeichen jeder Zeile in der Eingabe.

Nichts davon ist von Bedeutung, wenn Sie sicher sind, dass es sich bei Ihrer Eingabe um eine einzelne Zeile handelt, sie haben alle den gleichen Effekt.

158
paxdiablo

der einfachste Weg ist

${string:position:length}

Wo dies extrahiert $length Teilzeichenfolge von $string beim $position.

Dies ist eine eingebaute Bash, so dass awk oder sed nicht erforderlich ist.

44
ennuikiller

Sie haben mehrere gute Antworten bekommen und ich würde mit dem eingebauten Bash gehen, aber seitdem Sie nach sed und awk und (fast) niemand anderem gefragt haben Darauf aufbauend angebotene Lösungen biete ich Ihnen an:

echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'

und

echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'

Das awk sollte ziemlich offensichtlich sein, aber hier ist eine Erklärung des sed:

  • ersatz "s /"
  • die Gruppe "()" zweier beliebiger Zeichen "..", beginnend am Anfang der Zeile "^" und gefolgt von einem beliebigen Zeichen "." Null oder mehrmals "*" wiederholt (die Backslashes werden benötigt, um einige der Sonderzeichen zu maskieren)
  • durch "/" den Inhalt der ersten (und in diesem Fall einzigen) Gruppe (hier ist der Backslash ein spezielles Escape, das auf einen übereinstimmenden Unterausdruck verweist)
  • getan "/"
31

Wenn Sie in bash sind, können Sie sagen:

bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab

Das könnte genau das sein, was Sie brauchen ...

7

Grep einfach:

echo 'abcdef' | grep -Po "^.."        # ab
7
Amir Mehler

Ziemlich spät, aber jetzt ist es soweit

sed 's/.//3g'

Oder

awk NF=1 FPAT=..

Oder

Perl -pe '$_=unpack a2'
4
Steven Penny

colrm - Spalten aus einer Datei entfernen

Um die ersten beiden Zeichen zu belassen, entfernen Sie einfach die Spalten ab 3

cat file | colrm 3
4
Ian Yang

Wenn Sie Shell-Scripting verwenden möchten und sich nicht auf Nicht-Posix-Erweiterungen (z. B. sogenannte Bashismen) verlassen möchten, können Sie Techniken verwenden, für die keine externen Tools wie grep, sed, cut, awk usw. erforderlich sind Machen Sie Ihr Skript weniger effizient. Vielleicht ist Effizienz und Portabilität in Ihrem Anwendungsfall nicht wichtig. Falls dies jedoch eine gute Gewohnheit ist, können Sie die folgenden Parametererweiterungsoptionen verwenden, um die ersten beiden Zeichen einer Shell zu extrahieren Variable:

$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab

Dies verwendet die Parametererweiterung "Kleinstes Präfix" , um die ersten beiden Zeichen zu entfernen (dies ist das ${var#??} Teil), dann "kleinstes Suffix" Parametererweiterung (das ${var% part), um diese Zeichenfolge mit Ausnahme der ersten zwei Zeichen aus dem ursprünglichen Wert zu entfernen.

Diese Methode wurde zuvor in der Frage answer "Shell = Prüfen, ob Variable mit # beginnt" beschrieben. Diese Antwort beschreibt auch einige ähnliche Methoden zur Parametererweiterung, die in einem etwas anderen Kontext verwendet werden können als der, der hier für die ursprüngliche Frage gilt.

1
Juan

Sie können printf verwenden:

$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$orginal"
US
1
bschlueter

Wenn Ihr System eine andere Shell verwendet (nicht bash), Ihr System jedoch bash hat, können Sie weiterhin die inhärente Zeichenfolgenmanipulation von bash verwenden, indem Sie bash mit einer Variablen:

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;"
1
palswim
Perl -ple 's/^(..).*/$1/'
0
dsm

Ist es das, wonach du suchst?

my $string = 'USCAGoleta9311734.5021-120.1287855805';

my $first_two_chars = substr $string, 0, 2;

ref: substr

0
draegtun

if mystring = USCAGoleta9311734.5021-120.1287855805

print substr(mystring,0,2)

würde uns drucken

dabei steht 0 für die Startposition und 2 für die Anzahl der zu lesenden Zeichen

0
Jambobond