Verwenden Sie sed nicht für eine Datei, sondern für eine Zeichenfolgenvariable

30

Mir wurde gesagt, es sei möglich, aber ohne ein einziges funktionierendes Beispiel, das sedaus einer Zeichenfolgenvariablen lesen kann, ohne eine Eingabedatei zu benötigen. Ich muss es noch zum Laufen bringen. Zur allgemeinen Sicherheit schreibe ich die $PATHVariable in eine andere Variable, während ich damit herumspiele, da ich erst dann andere Probleme habe, wenn ich genau weiß, wie das geht.

Folgendes berücksichtigen:

~$x=$PATH
~$sed -i 's/:/ /g' $x

Dies schlägt fehl mit: Keine solche Datei oder Verzeichnis.

Hier sind einige andere, die ich ausprobiert habe:

~$ sed -i 's/:/ /g' | (read x) 
sed: no input files
~$ sed -i 's/:/ /g' | (read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' | $(read x) 
sed: no input files
~$ sed -i 's/:/ /g' | $(read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' < $(read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
bash: $(read $x): ambiguous redirect
~$ sed -i 's/:/ /g' < read $x 
bash: read: No such file or directory
~$ sed -i 's/:/ /g' < (read x) 
bash: syntax error near unexpected token `('
~$ sed -i 's/:/ /g' < $((read x)) 
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: syntax error: operand expected (error token is "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' < $((read $x)) 
bash: read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: division by 0 (error token is "usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' << $((read $x)) 
> ;^C
~$ sed -i 's/:/ /g' << $(read $x)
> ;^C
~$ sed -i 's/:/ /g' $x
sed: can't read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < $x
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < echo $x
bash: echo: No such file or directory
~$ sed -i 's/:/ /g' |  echo $x
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
sed: no input files

Kann das überhaupt funktionieren? Ich würde es vorziehen, keine Dateien schreiben zu müssen, die ich nicht brauche, nur damit ich sed verwenden kann. Wenn in diesem Beispiel ~$x=$PATH ~$sed -i 's/:/ /g' $xtatsächlich so gearbeitet hätte, wie ich es mir erhofft hätte, hätte ich Folgendes erhalten:

/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games

die ich dann einer variablen zuweisen und in zukünftigen befehlen verwenden könnte, wie ls $x

j0h
quelle
1
x=$(echo "$x" | sed 's/:/ /g')?
Heemayl

Antworten:

16

Vielleicht:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games
bolichep
quelle
@jOh --- beachte, dass sedhier nicht an der "string variable" (?) gearbeitet wird, sondern an der Standardeingabe --- so sollte es sein.
Rmano
Ich denke, ich mache eine Feature-Anfrage an die sed-Entwickler
j0h
4
@ j0h das hat nichts damit zu tun sed, es ist eine frage wie die shell eingaben umleitet. sedbehandelt Eingabeströme und liest sie über die Standardeingabe. Ob es sich um Dateien handelt oder nicht, ist unerheblich. Es kann alles akzeptieren, solange es über die Standardeingabe erfolgt.
Terdon
38

Dies hat nichts damit zu tun sed, sondern gilt für alle Programme, die Standardeingaben lesen. Wie auch immer, was Sie gesucht haben, ist

sed 's/:/ /g' <<<"$PATH"

Es gibt keinen Grund, in einer anderen Variablen zu speichern. Wenn Sie dies nicht tun, wirkt sich dies nicht auf den in der Variablen gespeicherten Wert aus. Dafür benötigen Sie den Zuweisungsoperator ( =). Die oben verwendete Syntax heißt "here string" und ist spezifisch für bash, ksh und zsh. Es dient dazu, den Wert einer Variablen als Eingabe an ein Programm zu übergeben, das von der Standardeingabe liest.

Ich habe eine Antwort auf U & L geschrieben , die alle verschiedenen Shell-Operatoren wie diesen auflistet. Vielleicht möchten Sie einen Blick darauf werfen.

Beachten Sie, dass Sie auch getan haben könnten

echo "$PATH" | sed 's/:/ /g' 

Zum Schluss brauchst du das wirklich gar nicht sed. Sie können das Ganze direkt in bash machen:

echo "${PATH//:/ }"

Das Obige ist ein Bash-Ersatzkonstrukt. Wenn Sie eine Variable $var, ein Muster patund ein repreplace ( ) angeben , würden Sie alle Vorkommen von patmit ersetzenrep

echo "${var//pat/rep}"

Dasselbe mit einem einzelnen Schrägstrich ersetzt nur das erste Vorkommen:

echo "${var/pat/rep}"
terdon
quelle
2
Danke für 'bash replacement construct'. Ich konnte: "$ {1 / from / to}" in einer Bash-Funktion verwenden, um das erste Argument in nachfolgende Parameter zu ändern.
AAAfarmclub,