2013-04-09 14 views
11

noob tutaj, przepraszam, jeśli repost. Ja wyodrębnianie ciąg znaków z pliku, a kończy się z linii, coś jak:Wyodrębnianie części ciągu do zmiennej w bash

abcdefg:12345:67890:abcde:12345:abcde 

Powiedzmy to w zmiennej o nazwie testString długość wartości między dwukropek nie jest stała, ale chcę aby zapisać liczbę, jako łańcuch znaków, w porządku, do zmiennej między drugim i trzecim dwukropkiem. więc w tym przypadku skończyłbym z moją nową zmienną, nazwijmy ją extractNum, czyli 67890. Zakładam, że muszę używać sed, ale nigdy go nie używałem i próbowałem się z tym pogodzić ... Czy ktoś może pomóc? Pozdrowienia

Na marginesie, używam find, aby wyodrębnić całą linię z ciągu znaków, wyszukując pierwszy ciąg znaków, w tym przypadku część abcdefg.

+0

możliwy duplikat [Jak przyciąć spacje ze zmiennej bash?] (Http://stackoverflow.com/questions/369758/how-to- trim-whitespace-from-bash-variable) – user2284570

Odpowiedz

9

Oto kolejny sposób czysty bash. Działa dobrze, gdy dane wejściowe są w miarę spójne i nie potrzebujesz dużej elastyczności w wybranej sekcji.

extractedNum="${testString#*:}"  # Remove through first : 
extractedNum="${extractedNum#*:}" # Remove through second : 
extractedNum="${extractedNum%%:*}" # Remove from next : to end of string 

Można także filtrować plik podczas czytania go w pętli while na przykład:

while IFS=' ' read -r col line ; do 
    # col has the column you wanted, line has the whole line 
    # # # 
done < <(sed -e 's/\([^:]*:\)\{2\}\([^:]*\).*/\2 &/' "yourfile") 

Polecenie sed jest wybieranie 2nd kolumnę i wyznaczające tę wartość z całej linii z przestrzeń. Jeśli nie potrzebujesz całej linii, po prostu usuń spację + & z zamiennika i upuść zmienną liniową z odczytu. Możesz wybrać dowolną kolumnę, zmieniając liczbę w bicie \ {2 \}. (Wpisz komendę w podwójnym cudzysłowie, jeśli chcesz użyć zmiennej tam.)

+0

Stary post, ale dlatego, że odpowiedź yr została przyjęta, czy można ją uzupełnić tak krótkim wyjaśnieniem składni "done <<(sed ...)"? (Część sed jest czysta, zastanawiam się nad dwoma od prawej do lewej przekierowaniem <. Tx. – Cbhihe

5

Możesz użyć cut dla tego rodzaju rzeczy. Proszę bardzo:

VAR=$(echo abcdefg:12345:67890:abcde:12345:abcde |cut -d":" -f3); echo $VAR 

Dla zabawy, to jak ja (nie) zrobić z sed, ale jestem pewien, że istnieje prostsze sposoby. Myślę, że byłoby to kwestia własną rękę do przyszłych czytelników;)

echo abcdefg:12345:67890:abcde:12345:abcde |sed -e "s/[^:]*:[^:]*:\([^:]*\):.*/\1/" 
+0

Dzięki za odpowiedź błyskawicy, zrobię to! –

+0

A w innej notatce, w jaki sposób później użyć tego później, aby umieścić ten numer z powrotem w nowym ciągu, zastępując to, co znajduje się między drugim a trzecim dwukropkiem? –

+0

Przypuszczam, że 'awt' jest lepiej dopasowany, im bardziej skomplikowany.Z sed można zrobić 'echo abcdefg: 12345: 67890: abcde: 12345: abcde | sed -e "s/\ ([^:] *: [^:] *: \) [^:] * \ (:. * \)/\ 1WHATEVER \ 2 /" ' – Miquel

2

ten powinien pracować dla Ciebie: kluczowym elementem jest awk -F: '$0=$3'

NewVar=$(getTheLineSomehow...|awk -F: '$0=$3') 

przykład:

kent$ newVar=$(echo "abcdefg:12345:67890:abcde:12345:abcde"|awk -F: '$0=$3') 

kent$ echo $newVar 
67890 

jeśli Twój tekst był zapisany w zmiennej testString, możesz:

kent$ echo $testString                                      
abcdefg:12345:67890:abcde:12345:abcde 
kent$ newVar=$(awk -F: '$0=$3' <<<"$testString") 
kent$ echo $newVar                                       
67890 
13

Czysta atakujących za pomocą tablicy:

testString="abcdefg:12345:67890:abcde:12345:abcde" 
IFS=':' 
array=($testString) 
echo "value = ${array[2]}" 

Wyjście:

value = 67890 
+0

Bardzo elegancki (+1), ale (niestety) tylko dla tablic obsługujących powłoki linuksowe takie jak bash! – Cbhihe

+2

Jestem pewna, że ​​to, o co prosił OP ... bash –

Powiązane problemy