Ini menggantikan semua :dalam $PATHoleh newline ( \n) dan mencetak hasilnya. Konten $PATHtetap tidak berubah.
Jika Anda hanya ingin mengganti yang pertama :, hapus garis miring kedua:echo -e "${PATH/:/\n}"
Saya pikir ini adalah solusi terbaik karena dilakukan dalam bash murni .
ryanmjacobs
1
@ryanmjacobs agak penasaran: menurut Anda apa solusi yang saya gunakan? : D
muru
1
tolong jelaskan cara kerjanya.
Tulains Córdova
Apa jenis operasi yang disebut? Ini mirip dengan sed tetapi tidak sed. Apa nama itu sehingga saya bisa mencari di web untuk info lebih lanjut tentang itu.
Tulains Córdova
3
Ikuti tautan (Ekspansi Parameter) dalam jawaban saya dan gulir ke bawah ke bagian kedua terakhir yang disebut:${parameter/pattern/string}
Cyrus
27
Menggunakan IFS:
(set-f; IFS=:; printf "%s\n" $PATH)
IFSmemegang karakter tempat bash melakukan pemisahan, jadi sebuah IFSdengan :membuat bash membagi ekspansi $PATHon :. printfloop argumen di atas string format sampai argumen habis. Kita perlu menonaktifkan globbing (ekspansi wildcard) set -fagar wildcard dalam nama direktori PATH tidak diperluas.
apakah variasi dalam hal ini, seperti echo $PATH | xargs -n1 -d: echoberlebihan atau tidak masalah?
Sergiy Kolodyazhnyy
@Serg echo $PATH | xargs -n1 -d: akan melakukan hal yang sama untuk Anda tetapi Anda akan menggunakan satu shell lagi. Yang pertama akan mengevaluasi echo $PATHdan menyalurkan output ke shell berikutnya untuk melakukan sisanya.
souravc
7
Inilah yang setara di Go:
$ cat path.go
package main
import ("fmt""os""strings")
func main(){for _, p := range strings.Split(os.Getenv("PATH"),":"){
fmt.Println(p)}}
$ go run path.go
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/nathan/.local/bin
/home/nathan/go/bin
Berikut adalah beberapa pendekatan lagi. Saya menggunakan a PATHdengan direktori yang berisi garis miring terbalik, spasi dan bahkan baris baru untuk menunjukkan bahwa mereka harus bekerja dengan apa pun (kecuali cutyang gagal pada baris baru):
$ echo "$PATH"/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even
new lines
The -pberarti "mencetak setiap baris masukan setelah menerapkan script yang diberikan oleh -e". Skrip menggunakan operator substitusi ( s/oldnew/) untuk mengganti semua :dengan baris baru.
$ perl -lne 'print for split /:/'<<<"$PATH"/bin
usr/bin//usr/local/bin
/some\ horrible thing
/even
new lines
The -lmenambahkan baris baru untuk setiap printpanggilan. Di sini, skrip membagi inputnya :dan kemudian mengulangi setiap elemen yang terpecah dan mencetaknya.
The -amerek perlberperilaku seperti awk: itu akan membagi masing-masing jalur input pada karakter yang diberikan oleh -F(jadi :, di sini) dan menyimpan hasilnya dalam array @F. Ini $"adalah variabel Perl khusus, "pemisah daftar", yang nilainya dicetak di antara setiap elemen daftar yang dicetak. Jadi pengaturannya ke baris baru akan membuat print @listmencetak setiap elemen @listdan kemudian baris baru. Di sini, kami menggunakannya untuk mencetak @F.
Gagasan yang sama seperti di atas, hanya kurang golf. Alih-alih menggunakan $", kami secara eksplisit joinmenggunakan array dengan baris baru dan kemudian mencetak.
The -omerek grepmencetak hanya bagian pencocokan setiap baris, sehingga setiap pertandingan dicetak pada baris terpisah. Yang -Pmemungkinkan Perl Kompatibel Regular Expressions (PCRE). Regex mencari rentang non- :( [^:]+) yang mengikuti awal baris ( ^) atau :karakter. Ini \Kadalah trik PCRE yang berarti "membuang apa pun yang cocok sebelum titik ini" dan digunakan di sini untuk menghindari pencetakan :juga.
Dan cutsolusinya (yang ini gagal pada baris baru, tetapi bisa berurusan dengan garis miring terbalik dan spasi):
Opsi yang digunakan adalah -d:yang mengatur pembatas input :, -f 1-yang berarti mencetak semua bidang (dari tanggal 1 hingga akhir) dan --output-delimiter=$'\n'yang menetapkan pembatas keluaran, baik,. The $'\n'adalah ANSI C mengutip dan merupakan cara untuk mencetak karakter baris baru di shell.
Dalam semua contoh di atas, saya menggunakan operator string ( <<<) di bash's (dan beberapa shells lainnya ) untuk meneruskan string sebagai input ke sebuah program. Jadi command <<<"foo"setara dengan echo -n "foo" | command. Perhatikan bahwa saya selalu mengutip "$PATH", tanpa tanda kutip, shell akan memakan karakter baris baru.
@ 7stud memberikan pendekatan lain dalam komentar yang terlalu bagus untuk tidak menyertakan:
$ perl -0x3a-l012 -pe ''<<<"$PATH"
Itulah yang dikenal sebagai golf . The -0menetapkan rekor pemisah masukan sebagai bilangan oktal atau heksadesimal. Inilah yang mendefinisikan "garis" dan nilai defaultnya adalah \n, karakter baris baru. Di sini, kita sedang menyiapkan itu untuk :yang x3adi hex (try printf '\x3a\n'). Ada -ltiga hal. Pertama menghilangkan pemisah record input ( $/) dari akhir setiap baris-efektif menghapus :sini-dan kedua, ia menetapkan pemisah record keluaran ( $\) untuk apa pun yang oktal atau nilai hex itu diberikan ( 012adalah \n). Jika $\ditentukan, ditambahkan ke akhir setiap printpanggilan, sehingga ini akan menghasilkan baris baru yang ditambahkan ke masing-masing print.
The -pekehendak p etak setiap baris masukan setelah menerapkan script yang diberikan oleh -e. Di sini tidak ada skrip karena semua pekerjaan dilakukan oleh flag opsi seperti yang dijelaskan di atas!
Perl satu liner Anda tidak cukup tidak jelas! Berikut adalah versi mana tidak ada kode untuk beralih -e untuk mengeksekusi karena switch lain menangani semuanya: perl -0x3a -l012 -pe '' <<<$PATH. Penjelasan: -0mengatur pemisah rekaman input (ditentukan dalam notasi heks / oktal, x3A adalah titik dua), -lmelakukan dua hal: 1) mengompol pemisah catatan input, 2) mengatur pemisah catatan keluaran jika ditentukan, (dalam notasi oktal) , 012 adalah baris baru). Sebuah -ploop mencetak nilai $ _, yang akan menjadi setiap baris yang dibaca.
7stud
Juga mencatat bahwa contoh Anda menggunakan -Fdapat menghilangkan -adan -nbendera, sebagai -F ternyata mereka secara otomatis: perl -F: -e 'print(join "\n", @F);' <<<$PATH. Lihat perlrun . Contoh yang bagus.
7stud
@ 7stud wow, itu benar-benar brilian, terima kasih! Tanpa malu-malu dicuri dan ditambahkan ke jawaban saya (saya anggap Anda tidak keberatan, silakan mempostingnya sendiri sebagai jawaban dan saya akan menghapusnya). Dan terima kasih atas -Finformasinya. Saya telah menggunakan -Fdikombinasikan dengan -anselama bertahun-tahun, saya tidak pernah menyadari yang tersirat yang lain. Ngomong-ngomong, saya melihat Serg menyebutkan Code Golf , tapi saya pikir Anda juga akan menikmati Unix & Linux jika Anda menyukai hal seperti ini.
terdon
Hei, terima kasih. Satu klarifikasi tentang pernyataan ini: Akhirnya, -ljuga menambahkan pemisah catatan keluaran yang diberikan pada akhir setiap panggilan cetak. Bahkan, cetak selalu menambahkan pemisah catatan keluaran $/,, ke akhir string - jika pemisah catatan keluaran ditentukan. Secara default itu adalah undef. Jadi hanya -lset $/, dan itu menyebabkan cetakan menambahkan baris baru ke akhir string.
7stud
Saya menganggap Anda tidak keberatan - Sama sekali tidak. :)
7stud
6
Dalam jawaban ini:
C
Python
Rubi
Alternatif awk
1. C
Karena semua bahasa skrip telah diambil, saya akan menggunakan C. Sangat mudah untuk mendapatkan variabel lingkungan dengan get_env()fungsi (lihat dokumentasi Perpustakaan C GNU ). Sisanya hanyalah manipulasi karakter
Ruby tidak datang dengan Ubuntu secara default, tidak seperti C compiler dan Python interpreter, tetapi jika Anda pernah menggunakannya, solusi di Ruby adalah sebagai berikut:
ruby -ne 'puts $_.split(":")'<<<"$PATH"
Seperti yang disarankan oleh 7stud (Terima kasih banyak!) Di komentar , ini juga dapat disingkat
Kita dapat menggunakan split()fungsi untuk memecah baris yang dibaca menjadi array, dan menggunakan for-eachloop untuk mencetak setiap item pada baris yang terpisah.
awk '{split($0,arr,":"); for(var in arr) print arr[var]}'<<< $PATH
Contoh ruby yang bagus. putssecara otomatis mencetak elemen-elemen array pada baris yang berbeda! Anda juga dapat membuat sakelar melakukan pemisahan: ruby -F: -ane 'puts $F' <<<$PATH Penjelasan: -Fmenetapkan $;ke karakter yang ditentukan, yang merupakan pemisah default yang digunakan oleh String :: split ($; memiliki nilai default nil, yang terbagi pada spasi putih). -apanggilan $ _. split, di mana $ _ adalah baris yang dibaca menggunakan gets ()) dan menetapkan array yang dihasilkan $F.
7stud
@ 7stud hei, terima kasih! :) Tidak tahu ada -Fflag - Saya baru memulai dengan Ruby, jadi melakukan hal-hal dengan cara yang agak kasar.
Sergiy Kolodyazhnyy
Tidak, ini barang yang tidak jelas. Satu liner Anda sangat mudah dibaca, dan kejelasan harus mengalahkan singkatnya setiap waktu.
7stud
Hah. Saya tahu satu lebih pendek: ruby -0072 -ne 'puts chomp' <<<$PATH. Penjelasan: -0mengatur pemisah rekaman input (tentukan karakter dalam format oktal; 072 adalah titik dua). Ruby menggunakan $ _ dengan cara yang mirip dengan Perl. Metode gets () (digunakan dalam -nloop) menetapkan $ _ ke baris saat ini yang dibaca. Dan chomp()tanpa arg, chomps $ _. Aku masih lebih suka milikmu. :)
7stud
@ 7stud sebenarnya, yang Anda posting sebelumnya, dengan -Fbendera, lebih pendek. Jika Anda melakukan echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c itu memberitahu saya itu 271, byte, tetapi yang dengan angka oktal adalah 276. Itu untuk seluruh perintah, tentu saja, Jika kita menganggap hanya kode itu sendiri puts $Fjelas lebih pendek. :) Ngomong-ngomong, apakah Anda tahu tentang Code Golf ? Ini adalah situs untuk solusi teka-teki pemrograman dalam jumlah byte terpendek. Ada pertanyaan terkait dengan ini: codegolf.stackexchange.com/q/96334/55572
Sergiy Kolodyazhnyy
5
Mungkin satu-satunya cara yang belum disebutkan adalah cara saya menggunakannya selama bertahun-tahun:
echo $PATH | tr ":" "\n"
jadi, di .profile atau .bash_profile Anda atau apa pun, Anda dapat menambahkan:
Awk lebih pendek:echo $PATH | awk '{gsub(/\:/,"\n");print}'
Sergiy Kolodyazhnyy
Saya tidak yakin mengapa Anda repot-repot fileinputketika Anda bisa menggunakan input:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
wjandrea
2
Saya menggunakan "Fungsi Bash Path" Stephen Collyer (lihat artikelnya di Linux Journal ). Ini memungkinkan saya untuk menggunakan "daftar terpisah usus" sebagai datatype dalam pemrograman shell. Sebagai contoh, saya dapat menghasilkan daftar semua direktori di direktori saat ini dengan:
dirs="";for i in*;doif[-d $i ];then addpath -p dirs $i;fi;done
Cara AWK lainnya adalah memperlakukan setiap direktori sebagai catatan terpisah , bukan sebagai bidang terpisah .
awk 'BEGIN{RS=":"} {print $0}'<<<"$PATH"
Saya menemukan bahwa sintaks sangat intuitif. Tetapi, jika Anda suka, Anda dapat mempersingkatnya dengan membuat yang print $0tersirat (itu adalah tindakan default, dan 1mengevaluasi menjadi true, menyebabkannya dilakukan untuk setiap baris):
awk 'BEGIN{RS=":"} 1'<<<"$PATH"
Input default dan pemisah catatan keluaran AWK adalah baris baru (line break). Dengan mengatur pemisah rekaman input ( RS) ke :sebelum membaca input, AWK secara otomatis mem-parsing sebuah usus yang dipisahkan $PATHmenjadi nama direktori konstituennya. AWK mengembang $0ke setiap keseluruhan rekaman, baris baru tetap menjadi pemisah rekaman keluaran , dan tidak perlu perulangan atau gsubdiperlukan.
AWK sering digunakan untuk mem-parsing catatan ke bidang yang terpisah, tetapi tidak perlu untuk itu hanya untuk membangun daftar nama direktori.
Ini berfungsi bahkan untuk input yang berisi kosong (spasi dan tab), bahkan beberapa kosong berturut-turut:
ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}'<<<$'ab\t\t c:de fg:h'
ab c
de fg
h
Artinya, kecuali Anda menyebabkan AWK untuk membangun kembali catatan (lihat di bawah), tidak ada masalah untuk memiliki spasi atau tab (pemisah bidang default) di input. Anda PATHmungkin tidak mengandung spasi pada sistem Ubuntu, tetapi jika itu, ini masih berfungsi.
Perlu disebutkan, sebagai catatan, bahwa kemampuan AWK untuk menafsirkan catatan sebagai kumpulan bidang menjadi berguna untuk masalah terkait membangun tabel komponen direktori :
ek@Io:~$ awk -F/'BEGIN{RS=":"; OFS="\t"} {$1=$1; print $0}'<<<"$PATH"
home ek bin
usr local sbin
usr local bin
usr sbin
usr bin
sbin
bin
usr games
usr local games
snap bin
(Ini mungkin lebih berguna untuk kasus-kasus di mana pemrosesan tambahan harus dilakukan pada komponen, daripada untuk contoh yang tepat ditampilkan hanya dengan mencetak tabel.)
Ini adalah cara yang saya sukai untuk melakukan ini berdasarkan kasus penggunaan saya masing-masing dan masalah tentang kompatibilitas dan penggunaan sumber daya.
tr
Pertama, jika Anda membutuhkan solusi yang cepat, mudah diingat, dan mudah dibaca, cukup gema PATHdan pipa untuk menerjemahkan ( tr) untuk mengubah titik dua menjadi baris baru:
echo $PATH | tr :"\n"
Kelemahan dari menggunakan dua proses karena pipa, tetapi jika kita hanya meretas terminal, apakah kita benar-benar peduli tentang itu?
Ekspansi parameter shell Bash
Jika Anda menginginkan solusi yang cukup permanen .bashrcuntuk penggunaan interaktif, Anda dapat alias menjalankan perintah berikut path, tetapi keterbacaan solusi ini dipertanyakan:
alias path="echo \"${PATH//:/$'\n'}\""
Jika pola dimulai dengan '/', semua kecocokan pola diganti dengan string. Biasanya hanya pertandingan pertama yang diganti.
Perintah di atas menggantikan titik dua dengan baris baru menggunakan Ekspansi Parameter Shell Bash :
${parameter/pattern/string}
Untuk menjelaskannya:
# v--v---------delimiters, a'la sed
echo "${PATH//:/$'\n'}"# ^^ ^^^^^----string, $ required to get newline character.# \----------pattern, / required to substitute for *every* :.
Semoga beruntung mengingat ini ketika Anda baru saja meretas pada baris perintah, jika Anda belum alias.
IFS, diuji dalam Bash dan Dash
Atau, pendekatan yang cukup kompatibel lintas, dapat dibaca, dan dimengerti yang tidak bergantung pada apa pun selain shell menggunakan fungsi berikut (saya sarankan di Anda .bashrc .)
Fungsi berikut untuk sementara membuat Pemisah Lapangan (IFS) Internal (atau Input) sebuah titik dua, dan ketika sebuah array diberikan printf, ia dijalankan sampai array habis:
path (){local IFS=:
printf "%s\n" ${PATH}}
Metode pembuatan fungsi , IFSdan printfdisediakan oleh POSIX, sehingga harus bekerja di sebagian besar POSIX-seperti kerang (terutama Dash, yang Ubuntu biasanya alias sebagaish ).
Python
Haruskah Anda menggunakan Python untuk ini? Anda bisa. Ini adalah perintah Python terpendek yang dapat saya pikirkan untuk ini:
Jawaban:
Coba
sed
:Atau
tr
:Atau
python
:Di sini semua hal di atas akan menggantikan semua kemunculan
:
dengan baris baru\n
.sumber
python -c 'import sys;print sys.argv[1].replace(":","\n")' $PATH
python -c "print r'$PATH'.replace(':', '\n')"
(menggunakan string mentah untuk backslash)tr
bekerja untuk saya (di mac, btw). Terima kasih..bash_profile
, tambahkan seperti ini:alias path='tr ":" "\n" <<< "$PATH"'
Gunakan Ekspansi Parameter bash :
Ini menggantikan semua
:
dalam$PATH
oleh newline (\n
) dan mencetak hasilnya. Konten$PATH
tetap tidak berubah.Jika Anda hanya ingin mengganti yang pertama
:
, hapus garis miring kedua:echo -e "${PATH/:/\n}"
sumber
${parameter/pattern/string}
Menggunakan IFS:
IFS
memegang karakter tempat bash melakukan pemisahan, jadi sebuahIFS
dengan:
membuat bash membagi ekspansi$PATH
on:
.printf
loop argumen di atas string format sampai argumen habis. Kita perlu menonaktifkan globbing (ekspansi wildcard)set -f
agar wildcard dalam nama direktori PATH tidak diperluas.sumber
Menggunakan
xargs
:Dari
man xargs
sumber
echo $PATH | xargs -n1 -d: echo
berlebihan atau tidak masalah?echo $PATH | xargs -n1 -d:
akan melakukan hal yang sama untuk Anda tetapi Anda akan menggunakan satu shell lagi. Yang pertama akan mengevaluasiecho $PATH
dan menyalurkan output ke shell berikutnya untuk melakukan sisanya.Inilah yang setara di Go:
sumber
Berikut adalah beberapa pendekatan lagi. Saya menggunakan a
PATH
dengan direktori yang berisi garis miring terbalik, spasi dan bahkan baris baru untuk menunjukkan bahwa mereka harus bekerja dengan apa pun (kecualicut
yang gagal pada baris baru):Beberapa cara Perl:
The
-p
berarti "mencetak setiap baris masukan setelah menerapkan script yang diberikan oleh-e
". Skrip menggunakan operator substitusi (s/oldnew/
) untuk mengganti semua:
dengan baris baru.The
-l
menambahkan baris baru untuk setiapprint
panggilan. Di sini, skrip membagi inputnya:
dan kemudian mengulangi setiap elemen yang terpecah dan mencetaknya.The
-a
merekperl
berperilaku sepertiawk
: itu akan membagi masing-masing jalur input pada karakter yang diberikan oleh-F
(jadi:
, di sini) dan menyimpan hasilnya dalam array@F
. Ini$"
adalah variabel Perl khusus, "pemisah daftar", yang nilainya dicetak di antara setiap elemen daftar yang dicetak. Jadi pengaturannya ke baris baru akan membuatprint @list
mencetak setiap elemen@list
dan kemudian baris baru. Di sini, kami menggunakannya untuk mencetak@F
.Gagasan yang sama seperti di atas, hanya kurang golf. Alih-alih menggunakan
$"
, kami secara eksplisitjoin
menggunakan array dengan baris baru dan kemudian mencetak.Sederhana
grep
dengan sihir PCRE:The
-o
merekgrep
mencetak hanya bagian pencocokan setiap baris, sehingga setiap pertandingan dicetak pada baris terpisah. Yang-P
memungkinkan Perl Kompatibel Regular Expressions (PCRE). Regex mencari rentang non-:
([^:]+
) yang mengikuti awal baris (^
) atau:
karakter. Ini\K
adalah trik PCRE yang berarti "membuang apa pun yang cocok sebelum titik ini" dan digunakan di sini untuk menghindari pencetakan:
juga.Dan
cut
solusinya (yang ini gagal pada baris baru, tetapi bisa berurusan dengan garis miring terbalik dan spasi):Opsi yang digunakan adalah
-d:
yang mengatur pembatas input:
,-f 1-
yang berarti mencetak semua bidang (dari tanggal 1 hingga akhir) dan--output-delimiter=$'\n'
yang menetapkan pembatas keluaran, baik,. The$'\n'
adalah ANSI C mengutip dan merupakan cara untuk mencetak karakter baris baru di shell.Dalam semua contoh di atas, saya menggunakan operator string (
<<<
) di bash's (dan beberapa shells lainnya ) untuk meneruskan string sebagai input ke sebuah program. Jadicommand <<<"foo"
setara denganecho -n "foo" | command
. Perhatikan bahwa saya selalu mengutip"$PATH"
, tanpa tanda kutip, shell akan memakan karakter baris baru.@ 7stud memberikan pendekatan lain dalam komentar yang terlalu bagus untuk tidak menyertakan:
Itulah yang dikenal sebagai golf . The
-0
menetapkan rekor pemisah masukan sebagai bilangan oktal atau heksadesimal. Inilah yang mendefinisikan "garis" dan nilai defaultnya adalah\n
, karakter baris baru. Di sini, kita sedang menyiapkan itu untuk:
yangx3a
di hex (tryprintf '\x3a\n'
). Ada-l
tiga hal. Pertama menghilangkan pemisah record input ($/
) dari akhir setiap baris-efektif menghapus:
sini-dan kedua, ia menetapkan pemisah record keluaran ($\
) untuk apa pun yang oktal atau nilai hex itu diberikan (012
adalah\n
). Jika$\
ditentukan, ditambahkan ke akhir setiapprint
panggilan, sehingga ini akan menghasilkan baris baru yang ditambahkan ke masing-masingprint
.The
-pe
kehendak p etak setiap baris masukan setelah menerapkan script yang diberikan oleh-e
. Di sini tidak ada skrip karena semua pekerjaan dilakukan oleh flag opsi seperti yang dijelaskan di atas!sumber
perl -0x3a -l012 -pe '' <<<$PATH
. Penjelasan:-0
mengatur pemisah rekaman input (ditentukan dalam notasi heks / oktal, x3A adalah titik dua),-l
melakukan dua hal: 1) mengompol pemisah catatan input, 2) mengatur pemisah catatan keluaran jika ditentukan, (dalam notasi oktal) , 012 adalah baris baru). Sebuah-p
loop mencetak nilai $ _, yang akan menjadi setiap baris yang dibaca.-F
dapat menghilangkan-a
dan-n
bendera, sebagai -F ternyata mereka secara otomatis:perl -F: -e 'print(join "\n", @F);' <<<$PATH
. Lihat perlrun . Contoh yang bagus.-F
informasinya. Saya telah menggunakan-F
dikombinasikan dengan-an
selama bertahun-tahun, saya tidak pernah menyadari yang tersirat yang lain. Ngomong-ngomong, saya melihat Serg menyebutkan Code Golf , tapi saya pikir Anda juga akan menikmati Unix & Linux jika Anda menyukai hal seperti ini.-l
juga menambahkan pemisah catatan keluaran yang diberikan pada akhir setiap panggilan cetak. Bahkan, cetak selalu menambahkan pemisah catatan keluaran$/
,, ke akhir string - jika pemisah catatan keluaran ditentukan. Secara default itu adalah undef. Jadi hanya-l
set$/
, dan itu menyebabkan cetakan menambahkan baris baru ke akhir string.Dalam jawaban ini:
1. C
Karena semua bahasa skrip telah diambil, saya akan menggunakan C. Sangat mudah untuk mendapatkan variabel lingkungan dengan
get_env()
fungsi (lihat dokumentasi Perpustakaan C GNU ). Sisanya hanyalah manipulasi karakter2. Python
Tetapi juga karena "mengapa tidak", inilah versi python alternatif melalui argumen baris perintah
sys.argv
3. Ruby
Ruby tidak datang dengan Ubuntu secara default, tidak seperti C compiler dan Python interpreter, tetapi jika Anda pernah menggunakannya, solusi di Ruby adalah sebagai berikut:
Seperti yang disarankan oleh 7stud (Terima kasih banyak!) Di komentar , ini juga dapat disingkat
dan dengan cara ini
4. Alternatif awk
Kita dapat menggunakan
split()
fungsi untuk memecah baris yang dibaca menjadi array, dan menggunakanfor-each
loop untuk mencetak setiap item pada baris yang terpisah.sumber
puts
secara otomatis mencetak elemen-elemen array pada baris yang berbeda! Anda juga dapat membuat sakelar melakukan pemisahan:ruby -F: -ane 'puts $F' <<<$PATH
Penjelasan:-F
menetapkan$;
ke karakter yang ditentukan, yang merupakan pemisah default yang digunakan oleh String :: split ($; memiliki nilai default nil, yang terbagi pada spasi putih).-a
panggilan $ _. split, di mana $ _ adalah baris yang dibaca menggunakan gets ()) dan menetapkan array yang dihasilkan$F
.-F
flag - Saya baru memulai dengan Ruby, jadi melakukan hal-hal dengan cara yang agak kasar.ruby -0072 -ne 'puts chomp' <<<$PATH
. Penjelasan:-0
mengatur pemisah rekaman input (tentukan karakter dalam format oktal; 072 adalah titik dua). Ruby menggunakan $ _ dengan cara yang mirip dengan Perl. Metode gets () (digunakan dalam-n
loop) menetapkan $ _ ke baris saat ini yang dibaca. Danchomp()
tanpa arg, chomps $ _. Aku masih lebih suka milikmu. :)-F
bendera, lebih pendek. Jika Anda melakukanecho "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c
itu memberitahu saya itu 271, byte, tetapi yang dengan angka oktal adalah 276. Itu untuk seluruh perintah, tentu saja, Jika kita menganggap hanya kode itu sendiriputs $F
jelas lebih pendek. :) Ngomong-ngomong, apakah Anda tahu tentang Code Golf ? Ini adalah situs untuk solusi teka-teki pemrograman dalam jumlah byte terpendek. Ada pertanyaan terkait dengan ini: codegolf.stackexchange.com/q/96334/55572Mungkin satu-satunya cara yang belum disebutkan adalah cara saya menggunakannya selama bertahun-tahun:
echo $PATH | tr ":" "\n"
jadi, di .profile atau .bash_profile Anda atau apa pun, Anda dapat menambahkan:
alias path='echo $PATH | tr ":" "\n"'
sumber
Kami membutuhkan lebih banyak Jawa!
Simpan ini untuk
GetPathByLine.java
, dan kompilasi menggunakan:Jalankan dengan:
sumber
python3 -c "import os; [print(p) for p in os.getenv('PATH').split(':')]"
Melalui awk.
Melalui python.
Perhatikan bahwa Indentasi sangat penting dalam python.
sumber
echo $PATH | awk '{gsub(/\:/,"\n");print}'
fileinput
ketika Anda bisa menggunakaninput
:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
Saya menggunakan "Fungsi Bash Path" Stephen Collyer (lihat artikelnya di Linux Journal ). Ini memungkinkan saya untuk menggunakan "daftar terpisah usus" sebagai datatype dalam pemrograman shell. Sebagai contoh, saya dapat menghasilkan daftar semua direktori di direktori saat ini dengan:
Kemudian,
listpath -p dirs
buat daftar.sumber
Penjelasan untuk jawaban @Cyrus
Catatan:
ANSI-C Quoting - menjelaskan $ 'some \ ntext'
Ekspansi Parameter Shell - menjelaskan $ {parameter / pattern / string}, Jika pola dimulai dengan '/', semua kecocokan pola diganti dengan string.
Jadi kita punya:
sumber
Cara AWK lainnya adalah memperlakukan setiap direktori sebagai catatan terpisah , bukan sebagai bidang terpisah .
Saya menemukan bahwa sintaks sangat intuitif. Tetapi, jika Anda suka, Anda dapat mempersingkatnya dengan membuat yang
print $0
tersirat (itu adalah tindakan default, dan1
mengevaluasi menjadi true, menyebabkannya dilakukan untuk setiap baris):Input default dan pemisah catatan keluaran AWK adalah baris baru (line break). Dengan mengatur pemisah rekaman input (
RS
) ke:
sebelum membaca input, AWK secara otomatis mem-parsing sebuah usus yang dipisahkan$PATH
menjadi nama direktori konstituennya. AWK mengembang$0
ke setiap keseluruhan rekaman, baris baru tetap menjadi pemisah rekaman keluaran , dan tidak perlu perulangan ataugsub
diperlukan.AWK sering digunakan untuk mem-parsing catatan ke bidang yang terpisah, tetapi tidak perlu untuk itu hanya untuk membangun daftar nama direktori.
Ini berfungsi bahkan untuk input yang berisi kosong (spasi dan tab), bahkan beberapa kosong berturut-turut:
Artinya, kecuali Anda menyebabkan AWK untuk membangun kembali catatan (lihat di bawah), tidak ada masalah untuk memiliki spasi atau tab (pemisah bidang default) di input. Anda
PATH
mungkin tidak mengandung spasi pada sistem Ubuntu, tetapi jika itu, ini masih berfungsi.Perlu disebutkan, sebagai catatan, bahwa kemampuan AWK untuk menafsirkan catatan sebagai kumpulan bidang menjadi berguna untuk masalah terkait membangun tabel komponen direktori :
Tugas penasaran
$1=$1
melayani tujuan memaksa AWK untuk membangun kembali catatan .(Ini mungkin lebih berguna untuk kasus-kasus di mana pemrosesan tambahan harus dilakukan pada komponen, daripada untuk contoh yang tepat ditampilkan hanya dengan mencetak tabel.)
sumber
sumber
Ini adalah cara yang saya sukai untuk melakukan ini berdasarkan kasus penggunaan saya masing-masing dan masalah tentang kompatibilitas dan penggunaan sumber daya.
tr
Pertama, jika Anda membutuhkan solusi yang cepat, mudah diingat, dan mudah dibaca, cukup gema
PATH
dan pipa untuk menerjemahkan (tr
) untuk mengubah titik dua menjadi baris baru:Kelemahan dari menggunakan dua proses karena pipa, tetapi jika kita hanya meretas terminal, apakah kita benar-benar peduli tentang itu?
Ekspansi parameter shell Bash
Jika Anda menginginkan solusi yang cukup permanen
.bashrc
untuk penggunaan interaktif, Anda dapat alias menjalankan perintah berikutpath
, tetapi keterbacaan solusi ini dipertanyakan:Perintah di atas menggantikan titik dua dengan baris baru menggunakan Ekspansi Parameter Shell Bash :
Untuk menjelaskannya:
Semoga beruntung mengingat ini ketika Anda baru saja meretas pada baris perintah, jika Anda belum alias.
IFS, diuji dalam Bash dan Dash
Atau, pendekatan yang cukup kompatibel lintas, dapat dibaca, dan dimengerti yang tidak bergantung pada apa pun selain shell menggunakan fungsi berikut (saya sarankan di Anda
.bashrc
.)Fungsi berikut untuk sementara membuat Pemisah Lapangan (IFS) Internal (atau Input) sebuah titik dua, dan ketika sebuah array diberikan
printf
, ia dijalankan sampai array habis:Metode pembuatan fungsi ,
IFS
danprintf
disediakan oleh POSIX, sehingga harus bekerja di sebagian besar POSIX-seperti kerang (terutama Dash, yang Ubuntu biasanya alias sebagaish
).Python
Haruskah Anda menggunakan Python untuk ini? Anda bisa. Ini adalah perintah Python terpendek yang dapat saya pikirkan untuk ini:
atau hanya Python 3 (dan mungkin lebih mudah dibaca?):
Ini harus bekerja di lingkungan shell biasa juga, selama Anda memiliki Python.
sumber
Solusi ini lebih sederhana daripada solusi Java , C , go and awk :
Berikut kemungkinan besar lainnya:
Ini akan membutuhkan beberapa dependensi untuk diinstal:
sumber