
Ich kann viele Fragen mit Antworten in die andere Richtung finden, aber leider nicht in die, in der ich meine Nachfolger haben möchte: Ich beabsichtige,Ersetzen eines Zeichens, wie zum Beispiel #
,in einer Zeichenfolge, wie test#asdf
, mit einer Sequenz wie{0..10}
um eine Folge von Zeichenfolgen zu erhalten, in diesem Beispiel test0asdf test1asdf test2asdf test3asdf test4asdf test5asdf test6asdf test7asdf test8asdf test9asdf test10asdf
.
Ich habe es versucht, von anderen:
echo '_#.test' | tr # {0..10}
(wirft Verwendung)echo '_#.test' | sed -r 's/#/{0..10}/g'
(kehrt zurück_{0..10}.test
)echo '_#.test' | sed -r 's/#/'{0..10}'/g'
(funktioniert beim ersten, danach bekomme ichsed: can't read (...) no such file or directory
)
Was ist ein funktionierender Ansatz für dieses Problem?
Edit, da ich noch nicht kommentieren darf: Ich muss #
den String, in dem dieses Zeichen ersetzt werden soll, so verwenden, als wäre er von einem anderen Programm übergeben worden. Ich könnte es aber vorher durch ein anderes Zeichen ersetzen.
Antwort1
Der {0..10}
zsh
Operator (der jetzt auch von einigen anderen Shells unterstützt wird, darunter bash
) ist lediglich eine andere Form der csh
Klammererweiterung im -Stil.
Es wird erweitertdurch die Schalebevor der Befehl aufgerufen wird. Der Befehl sieht diese nicht {0..10}
.
Mit tr '#' {0..10}
(in Anführungszeichen, da #
es sonst von der Shell als Kommentaranfang analysiert wird) tr
wird der Aufruf mit ("tr", "#", "0", "1", ..., "10") als Argumenten beendet und tr
erwartet nicht so viele Argumente.
Hier benötigen Sie:
echo '_'{0..10}'.test'
für echo
die Übergabe von "_0.test", "_1.test", ..., "_10.test" als Argumente.
Oder wenn Sie möchten, dass es #
in diesen Operator übersetzt wird {0..10}
, wandeln Sie es in Shellcode um, der ausgewertet werden soll:
eval "$(echo 'echo _#.test' | sed 's/#/{0..10}/')"
wobei als Argumente eval
übergeben wird .echo _{0..10}.test
(nicht, dass ich empfehlen würde, so etwas zu tun).
Antwort2
Du kannstTeiltdie Zeichenfolge als Trennzeichen, erfassen Sie das Präfix und das Suffix und verwenden Sie dann die Klammererweiterung, um die Namen zu generieren:
str='test#asdf'
IFS='#' read -r prefix suffix <<<"$str"
names=( "$prefix"{0..10}"$suffix" )
declare -p names
declare -a names='([0]="test0asdf" [1]="test1asdf" [2]="test2asdf" [3]="test3asdf" [4]="test4asdf" [5]="test5asdf" [6]="test6asdf" [7]="test7asdf" [8]="test8asdf" [9]="test9asdf" [10]="test10asdf")'
Antwort3
Müssen Sie verwenden #
? Vielleicht könnten Sie verwenden %d
?
$ for i in {1..10}; do printf "_%d.test " "$i"; done
_1.test _2.test _3.test _4.test _5.test _6.test _7.test _8.test _9.test _10.test
Antwort4
Ich würde es machen mitParametererweiterung:
$ var='test#asdf'
$ for i in {1..10}; do echo "${var/\#/"$i"}"; done
test1asdf
test2asdf
test3asdf
test4asdf
test5asdf
test6asdf
test7asdf
test8asdf
test9asdf
test10asdf
Die Erweiterung${parameter/pattern/string}
- nimmt die Erweiterung von (in unserem Fall ) und
$parameter
$var
- ersetzt das erste Vorkommen von
pattern
(das Escapezeichen#
–/#
hat im Kontext eine besondere Bedeutung, „Ersetzen am Anfang der Zeichenfolge“, was wir vermeiden möchten) mit string
("$i"
in unserem Fall)
Alternativ können Sie es #
durch ersetzen %d
und als Formatzeichenfolge für Folgendes verwenden printf
:
printf "${var/\#/%d}\\n" {1..10}