2010-05-20 10 views
171

mam ciąg jakWymiana niektórych znaków w ciąg z innym charakterem

AxxBCyyyDEFzzLMN 

Chcę wymienić wszystkie x i y i z z _ tak, że wyjście jest

A_BC_DEF_LMN 

Jak Zrób to?

wiem serię

echo "$string" | tr 'x' '_' | tr 'y' '_' 

będzie pracować, ale chcę to zrobić za jednym razem, bez użycia przewodów.

EDIT: Następujące pracował

echo "$string" | tr '[xyz]' '_' 
+0

Czy chcesz zastąpić sekwencję kolejnych x, y lub z za pomocą _one_ podkreślnika, czy też chcesz zastąpić _each_ x, y lub z jednym podkreśleniem? Co powiesz na mieszane sekwencje, takie jak 'AxyzB'? Trzy podkreślenia lub jeden? –

+0

'tr '[xyz]'' również zastąpi '[' i ']'. Argument powinien być po prostu listą znaków (chociaż zakresy takie jak "a-z" są w porządku, aw niektórych implementacjach klasy znaków POSIX, takie jak '[: cyfra:]'). – tripleee

Odpowiedz

195
echo "$string" | tr xyz _ 

zastąpi każde wystąpienie x, y lub z z _, dając A__BC___DEF__LMN w swoim przykładzie.

echo "$string" | sed -r 's/[xyz]+/_/g' 

zastąpi powtarzające się wystąpienia x, y lub z z jednym _, dając A_BC_DEF_LMN w swoim przykładzie.

+10

Na komputerze Mac, mam następujące: sed: niedozwolona opcja - r użycie: skrypt sed [-Ealn] [-i rozszerzenie] [plik ...] sed [-Ealn] [-i rozszerzenie] [- e skrypt] ... [-f plik_skryptu] ... [plik ...] – iOSdev

+0

Mam ciąg znaków zawierający znaki ', [] {}() ~'. Chcę go zastąpić każdym znakiem specjalnym, którego uniknięto przy użyciu '' \ '' , w jaki sposób mogę wykonać to za pomocą pojedynczego zdjęcia? – inckka

+2

@halakala Mac jest dostarczany z nieco inną wersją sed. Zobacz to pytanie: http://unix.stackexchange.com/questions/13711/differences-between-sed-on-mac-osx-and-other-standard-sed Zamiast tego możesz zainstalować "gnu-sed" z menedżerem pakietów Homebrew następnie użyj 'bsed 'binary:' $ brew install gnu-sed', a następnie '$ gsed -r' s/[xyz] +/_/g''' –

194

Korzystanie Bash Parameter Expansion:

orig="AxxBCyyyDEFzzLMN" 
mod=${orig//[xyz]/_} 
+0

dzięki. chciałem w tej formie chociaż ... (zobacz moją edycję avove) – Amarsh

+4

Złe podstawienie – Alexey

+1

@Alexey, mój przykład działa dla mnie (bash 4.3.11 (1) -release). Upewnij się, że używasz 'bash'. Inne powłoki mogą nie działać (choć niektóre będą). –

5
read filename ; 
sed -i 's/letter/newletter/g' "$filename" #letter 

^skorzystać jak najwięcej z nich, jak trzeba i można zrobić własny BASIC szyfrowanie

+0

fajny pomysł na kryptografię podmiany – Stephen

67

Można znaleźć ten link pomocny:

http://tldp.org/LDP/abs/html/string-manipulation.html

w ogóle,

Aby zastąpić pierwsze dopasowanie podłańcuchu $ zastępowaniem $:

${string/substring/replacement} 

Aby wymienić wszystkie mecze $ $ fragmentu z wymianą:

${string//substring/replacement} 

EDIT: Zauważ, że odnosi się to do zmiennej o nazwie $ string.

+8

Należy zauważyć, że działa to na ** zmiennej o nazwie "ciąg" ** nie w ciągu literału. – mattdm

+0

najbardziej przydatny, ponieważ zawiera odniesienie. – Os3

3

Oto rozwiązanie ze zwiększeniem parametrów powłoki, który zastępuje wiele zdarzeń sąsiadujących z jednym _:

$ var=AxxBCyyyDEFzzLMN 
$ echo "${var//+([xyz])/_}" 
A_BC_DEF_LMN 

Należy zauważyć, że wzór +(pattern) wymaga przedłużonego dopasowanie wzorca, włączone w

shopt -s extglob 

Alternatywnie , z opcją -s ("ściśnięcie") z tr:

$ tr -s xyz _ <<< "$var" 
A_BC_DEF_LMN