Jak używać grep na zmiennej lub łańcuchu?

2

Piszę skrypt basha i muszę sprawdzić, czy nazwa pliku ma numer na końcu (po kropce), a jeśli tak, to go zdobyć, ale nie mogę zrozumieć, jak używać wyrażenia regularnego na zmiennej lub łańcuchu.

Byłem w stanie użyć echo w terminalu do potoku łańcucha na grep, w ten sposób:

 echo "filename.txt.123" | egrep -o "\.[0-9]+$" | egrep -o "[0-9]+"

Ale muszę przypisać wyjście tego do zmiennej. Próbowałem to zrobić:

 revNumber= echo "filename.txt.123" | egrep -o "\.[0-9]+$" | egrep -o "[0-9]+"

Ale to nie działa. Spróbowałem też kilku innych rzeczy, ale nic nie było ważne.

W moim skrypcie bash chcę używać grep na zmiennej, a nie na łańcuchu, ale koncepcja tutaj jest taka sama.

Jak mogę użyć grep na łańcuchu lub zmiennej, a następnie zapisać wynik w innej zmiennej?

Nate
źródło
nie można go rozwiązać za pomocą cytatów zwrotnych. To jest składnia do uzyskania wyniku polecenia w zmiennej. r=`echo abc` echo $ r
barlop

Odpowiedzi:

5

Aby przypisać wyjście polecenia do zmiennej, użyj $():

revNumber=$(echo "filename.txt.123" | egrep -o "\.[0-9]+$" | egrep -o "[0-9]+")

Jeśli zależy ci tylko na tym pasujący , możesz rozważyć case:

case foo in
  f*) echo starts with f
   ;;
  *) echo does not start with f
   ;;
esac
sds
źródło
Dobra odpowiedź. Wiedziałem o formie backtick / backquote zastępowania poleceń, ale zapomniałem o $() Formularz.
Arkanon
@Arkanon: `` jest w starym stylu; $() jest czystszy.
sds
0

Dlaczego grep i echo I / O overkill, sugeruję użycie możliwości przetwarzania łańcuchów bash:

TESTFNAME="filename.txt.283" # you can collect this from doing an ls in the target directory

# acquire last extension using a regexp, including the '.':
FEXT=$(expr "$TESTFNAME" : '.*\(\.[[:digit:]][[:digit:]]*\)')

# check if length is more than just the dot, that means we've got digits:
if [  ${#FEXT} -gt 1 ]; then
    echo "Gotcha!" $testFilename ${#FEXT} $FEXT # do whatever you like with the file
fi

Wyrażenie regularne można zoptymalizować i nie jest idealne, ale oto podstawy:

  • . * na początku wyszuka na końcu pliku.
  • [[:cyfra::]] jest prawie taki sam jak [0-9], ale uważam, że jest bardziej czytelny

Sprawdź inne grzmotnąć możliwości manipulacji ciągami w TLDP tutaj .

Milen
źródło
0

Poniżej znajduje się kolejna opcja, która używa porównania wyrażeń regularnych bash przed wyodrębnieniem wartości na końcu łańcucha.

if [[ $TESTFNAME =~ \.[0-9]+$ ]]; then
  VAL=$(egrep -o '[0-9]+$' <<<"$TESTFNAME")
fi
Lenny
źródło