Usuń ciąg wiodący w bash

10

Mam ciąg jak rev00000010i chcę tylko ostatnią liczbę, w tym przypadku 10.

Próbowałem tego:

TEST='rev00000010'
echo "$TEST" | sed '/^[[:alpha:]][0]*/d'
echo "$TEST" | sed '/^rev[0]*/d'

oba zwracają nic, chociaż wyrażenie regularne wydaje się być poprawne (wypróbowano z wyrażeniem regularnym )

Michael Niemand
źródło
powiązane: stackoverflow.com/questions/16623835/…
Ciro Santilli 13 病毒 审查 六四 事件 法轮功

Odpowiedzi:

16

Polecenia, które przekazałeś, sedoznaczają: jeśli wiersz pasuje do wyrażenia regularnego, usuń go . Nie tego chcesz.

echo "$TEST" | sed 's/rev0*//'

Oznacza to: w każdej linii usuń rev, a następnie dowolną liczbę zer.

Nie potrzebujesz też sedtak prostej rzeczy. Wystarczy użyć bash i jego rozszerzenia parametrów :

shopt -s extglob         # Turn on extended globbing.
echo "${TEST##rev*(0)}"  # Remove everything from the beginning up to `rev`
                         # followed by the maximal number of zeroes.
choroba
źródło
5

POSIXly:

test='rev00000010'
number=${test#"${test%%[1-9]*}"}

Usuwałby wszystko po lewej stronie najbardziej niezerowej cyfry po lewej stronie.

Bournely / uniwersalnie:

number=`expr "x$test" : 'xrev0*\(.*\)'`
Stéphane Chazelas
źródło
Pierwszy rozpadnie się z kropkami, heksami, spacjami itp .: test='rev 003A0.1056'produkuje number="3A0.1056". Drugi zepsuje się na dowolnym polu, wytworzy tę samą wartość: 003A0.1056z wyraż.
3

Jeśli masz już zmienną TEST, po prostu wydrukuj ją z usuniętą całą literą

printf "%.0f\n" ${TEST//[a-z]/}

lub

printf "%g\n" ${TEST//[a-z]/}

Nie używaj %dlub echo-polecaj, ponieważ liczby z wiodącym 0są rozumiane jakooctal

Costas
źródło
2

Kilka dodatkowych opcji (choć zalecam również użycie rozszerzenia parametrów, jak sugeruje @choroba):

  • Użyj sedlub, perlaby zastąpić wszystko oprócz dwóch ostatnich znaków dwoma ostatnimi znakami. To skutecznie usuwa wszystko oprócz dwóch ostatnich.

    $ sed -r 's/.*(..)/\1/' <<<$TEST
    10
    $ perl -pe 's/.*(..)/\1/' <<<$TEST
    10
    
  • Ustaw awkogranicznik pola na 2 lub więcej zer i wydrukuj ostatnie pole:

    $ awk -F"00+" '{print $NF}' <<<$TEST
    10
    
  • Wyodrębnij tylko dwa ostatnie znaki:

    $ grep -oP '..$' <<<$TEST
    10
    $ perl -lne '/(..)$/; print $1' <<<$TEST
    10
    
  • Wydrukuj tylko 10-te ostatnie bajty:

    $ cut -b 10- <<<$TEST
    10
    

Zauważ, że wszystkie powyższe zastosowania, <<<$varktóre są konstrukcją bash. Aby użyć go w innych powłokach, zmień na echo "$TEST" | command.

terdon
źródło
1
Dla awk inny wariant, który może uniknąć pewnego problemuawk -F"[a-z]" '{print +$NF}'
Costas
0

Aby uzyskać „ostatnią liczbę”, wybierz dowolną sekwencję cyfr na końcu ciągu i przekonwertuj ją na liczbę dziesiętną:

Z Bash:

 [[ "$test" =~  ([1-9][0-9]*)$ ]] && echo "number: $((10#${BASH_REMATCH[1]}))"

Z grep:

echo "$test" | grep -Po "[1-9][0-9]*$"

źródło