Gunakan sed pada variabel string daripada file

30

Saya telah diberitahu bahwa itu mungkin, tetapi tanpa satu contoh kerja, yang seddapat membaca dari variabel string tanpa memerlukan file input. Saya belum membuatnya bekerja. Untuk keselamatan umum, saya menulis $PATHvariabel ke variabel lain, karena saya mengacaukan ini, karena saya tidak perlu masalah lain untuk muncul sampai saya tahu persis bagaimana melakukan ini.

Pertimbangkan yang berikut ini:

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

ini gagal dengan: Tidak ada file atau direktori tersebut.

Berikut beberapa yang sudah saya coba:

~$ 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

Bisakah ini bekerja? Saya lebih suka tidak perlu menulis file yang saya tidak perlu supaya saya bisa menggunakan sed. Untuk contoh khusus ini, jika ~$x=$PATH ~$sed -i 's/:/ /g' $xbenar-benar bekerja seperti yang saya harapkan, saya akan mendapatkan:

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

yang kemudian saya dapat tetapkan ke variabel, dan gunakan dalam perintah di masa depan, seperti ls $x

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

Jawaban:

16

Mungkin:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games
bolichep
sumber
@jOh --- perhatikan bahwa di sedsini tidak bekerja pada "variabel string" (?), tetapi pada input standar --- yang seharusnya.
Rmano
Saya pikir saya akan membuat permintaan fitur ke sed devs
j0h
4
@ j0h ini tidak ada hubungannya dengan sed, itu adalah pertanyaan tentang bagaimana shell mengarahkan ulang input. sedberurusan dengan aliran input dan membacanya melalui input standarnya. Apakah itu file atau tidak, tidak relevan. Ia dapat menerima apa saja asalkan melalui input standar.
terdon
38

Ini tidak ada hubungannya dengan seditu, itu berlaku untuk setiap program yang membaca input standar. Bagaimanapun, apa yang Anda cari adalah

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

Tidak ada alasan untuk menyimpan dalam variabel lain, tidak ada yang Anda lakukan dengan cara ini akan memengaruhi nilai yang disimpan dalam variabel. Anda memerlukan operator penugasan ( =) untuk itu. Sintaks yang digunakan di atas disebut "di sini string" dan khusus untuk bash, ksh dan zsh. Ini berfungsi untuk melewatkan nilai variabel sebagai input ke program yang membaca dari input standar.

Saya telah menulis jawaban pada U&L yang mencantumkan semua berbagai operator shell seperti ini. Anda mungkin ingin melihatnya.

Perhatikan bahwa Anda juga bisa melakukannya

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

Akhirnya, Anda benar-benar tidak perlu sedsama sekali untuk ini. Anda dapat melakukan semuanya di bash secara langsung:

echo "${PATH//:/ }"

Di atas adalah konstruksi pengganti bash. Diberikan variabel $var, pola, patdan pengganti ( rep), untuk mengganti semua kemunculan patdengan rep, Anda akan melakukannya

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

Hal yang sama dengan garis miring hanya menggantikan kejadian pertama:

echo "${var/pat/rep}"
terdon
sumber
2
Terima kasih untuk 'konstruksi pengganti bash'. Saya dapat menggunakan: "$ {1 / from / to}" dalam fungsi Bash untuk mengubah argumen pertama menjadi parameter berikutnya.
AAAfarmclub