Cách hiển thị các đường dẫn trong $ PATH riêng


45

Tôi không thể tìm ra cách liệt kê các đường dẫn khác nhau $PATHmột cách riêng biệt để chúng trông như thế này:

/bin
/usr/bin
/usr/local/bin

Vân vân.

Có ai biết biến chính xác cho điều này?


Mỗi đường dẫn phải nằm trên một dòng riêng biệt
HankG

Những gì nên được in nếu đường dẫn của bạn có chứa dòng mới?
Martijn


Câu trả lời:


57

Hãy thử sed:

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

Hoặc tr:

$ tr ':' '\n' <<< "$PATH"

Hoặc python:

$ python2 -c "import os; print os.environ['PATH'].replace(':', '\n')"

Ở đây tất cả những điều trên sẽ thay thế tất cả các lần xuất hiện :bằng các dòng mới \n.


Sự thay đổi trong cách tiếp cận con trăn của bạn:python -c 'import sys;print sys.argv[1].replace(":","\n")' $PATH
Sergiy Kolodyazhnyy

Một biến thể khác của Python, kinda hacky: python -c "print r'$PATH'.replace(':', '\n')"(sử dụng chuỗi thô trong trường hợp dấu gạch chéo ngược)
wjandrea

3
trlàm việc cho tôi (trên mac, btw). Cảm ơn.
Mike S.

Đối với những người, như tôi, những người muốn thêm nó vào của họ .bash_profile, hãy thêm nó như thế này:alias path='tr ":" "\n" <<< "$PATH"'
Mike S.

63

Sử dụng bash's Parameter Expansion :

echo "${PATH//:/$'\n'}"

Tất cả thay thông số này :trong $PATHbởi một dòng mới ( \n) và in kết quả. Nội dung $PATHvẫn không thay đổi.
Nếu bạn chỉ muốn thay thế dấu đầu tiên :, hãy xóa dấu gạch chéo thứ hai:echo -e "${PATH/:/\n}"


3
Tôi nghĩ rằng đây là giải pháp tốt nhất vì nó được thực hiện trong bash thuần túy .
ryanmjacobs 22/03/2015

1
@ryanmjacobs hơi tò mò: bạn nghĩ giải pháp của tôi sử dụng cái gì? : D
muru

1
hãy giải thích cách nó hoạt động.
Tulains Córdova

Loại hoạt động đó được gọi là gì? Nó tương tự như sed nhưng nó không phải là sed. Tên của nó là gì để tôi có thể tìm kiếm trên web để biết thêm thông tin về nó.
Tulains Córdova

3
Theo liên kết (Mở rộng tham số) trong câu trả lời của tôi và cuộn xuống phần thứ hai cuối cùng được gọi là:${parameter/pattern/string}
Cyrus

27

Sử dụng IFS:

(set -f; IFS=:; printf "%s\n" $PATH)

IFSgiữ các ký tự trên đó bash không tách, vì vậy một IFSvới :làm cho bash chia việc mở rộng $PATHtrên :. printflặp các đối số trên chuỗi định dạng cho đến khi hết đối số. Chúng ta cần vô hiệu hóa globalbing (mở rộng ký tự đại diện) bằng cách sử dụng set -fcác ký tự đại diện trong tên thư mục PATH không được mở rộng.


2
Điều này hoạt động chính xác với dấu gạch chéo ngược và dấu cách!
heinrich5991

14

Sử dụng xargs:

xargs -n1 -d: <<< $PATH

Từ man xargs

-n max-args
          Use  at  most  max-args  arguments per command line.

 -d delim
          Input  items  are terminated by the specified character.

sẽ thay đổi về điều này, chẳng hạn như echo $PATH | xargs -n1 -d: echolà dư thừa hoặc nó không quan trọng?
Sergiy Kolodyazhnyy

@Serg echo $PATH | xargs -n1 -d: sẽ làm điều tương tự cho bạn nhưng bạn sẽ sử dụng thêm một shell. Người đầu tiên sẽ đánh giá echo $PATHvà đầu ra ống cho vỏ tiếp theo để làm phần còn lại.
souravc

7

Đây là tương đương trong 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

7

Dưới đây là một vài cách tiếp cận. Tôi đang sử dụng một PATHthư mục chứa dấu gạch chéo ngược, dấu cách và thậm chí một dòng mới để cho thấy rằng chúng nên hoạt động với bất kỳ thứ gì (ngoại trừ dòng cutbị lỗi trên dòng mới):

$ echo "$PATH"
/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even 
new lines
  • Một số cách Perl:

    $ perl -pe 's/:/\n/g' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines

    -pnghĩa là "in mọi dòng đầu vào sau khi áp dụng tập lệnh được đưa ra bởi -e". Kịch bản đang sử dụng toán tử thay thế ( s/oldnew/) để thay thế tất cả :bằng các dòng mới.

    $ perl -lne 'print for split /:/' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines

    Việc -lthêm một dòng mới cho mỗi printcuộc gọi. Ở đây, tập lệnh đang phân tách đầu vào của nó :và sau đó lặp qua từng phần tử phân tách và in nó.

    $ perl -F: -ane '$"="\n";print "@F"' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines

    Việc -athực hiện perlgiống như awk: nó sẽ phân tách từng dòng đầu vào của nó trên ký tự được đưa ra bởi -F(vì vậy :, ở đây) và lưu kết quả trong mảng @F. Các $"là một biến Perl đặc biệt, "danh sách phân cách", có giá trị được in giữa mỗi phần tử của một danh sách in. Vì vậy, đặt nó thành một dòng mới sẽ làm cho print @listin từng phần tử @listvà sau đó là một dòng mới. Ở đây, chúng tôi đang sử dụng nó để in @F.

    $ perl -F: -ane 'print join "\n", @F' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines

    Ý tưởng tương tự như trên, chỉ cần ít chơi golf. Thay vì sử dụng $", chúng tôi rõ ràng joining mảng với dòng mới và sau đó in.

  • Đơn giản grepvới phép thuật PCRE:

    $ grep -oP '(^|:)\K[^:]+' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines

    Các -olàm cho grepchỉ in phần gắn kết của mỗi dòng, vì vậy mỗi trận đấu được in trên một dòng riêng biệt. Cho -Pphép biểu thức tương thích thường xuyên tương thích Perl (PCRE). Regex đang tìm kiếm các đoạn không :( [^:]+) đi theo đầu dòng ( ^) hoặc :ký tự. Đây \Klà một thủ thuật PCRE có nghĩa là "loại bỏ bất cứ thứ gì phù hợp trước thời điểm này" và được sử dụng ở đây để tránh in :.

  • Và một cutgiải pháp (điều này không thành công trên các dòng mới, nhưng có thể xử lý dấu gạch chéo ngược và dấu cách):

    $ cut -d: -f 1- --output-delimiter=$'\n' <<<"$PATH"
    /bin
    usr/bin/
    /usr/local/bin
    /some\ horrible thing
    /even 
    new lines

    Các tùy chọn được sử dụng là -d:đặt dấu phân cách đầu vào :, -f 1-có nghĩa là in tất cả các trường (từ đầu đến cuối) và --output-delimiter=$'\n'thiết lập dấu phân cách đầu ra, tốt, tốt. Đây $'\n'trích dẫn ANSI C và là một cách để in một ký tự dòng mới trong trình bao.

Trong tất cả các ví dụ trên, tôi đang sử dụng toán tử bash '(và một số shell khác') ở đây<<< toán tử chuỗi ( ) để truyền chuỗi dưới dạng đầu vào cho chương trình. Như vậy command <<<"foo"là tương đương với echo -n "foo" | command. Lưu ý rằng tôi luôn luôn trích dẫn "$PATH", nếu không có dấu ngoặc kép, shell sẽ ăn nhân vật dòng mới.


@ 7stud đã đưa ra một cách tiếp cận khác trong các ý kiến chỉ là quá tốt để không bao gồm:

$ perl -0x3a -l012 -pe '' <<<"$PATH"

Đó là những gì được gọi là golf . Chỉ -0định dấu phân cách bản ghi đầu vào là số bát phân hoặc thập lục phân. Đây là những gì định nghĩa một "dòng" và giá trị mặc định của nó là \n, một ký tự dòng mới. Ở đây, chúng ta đang cài đặt nó vào một :mà là x3atrong hex (thử printf '\x3a\n'). Có -lba điều. Đầu tiên, nó loại bỏ dấu tách bản ghi đầu vào ( $/) khỏi cuối mỗi dòng, loại bỏ một cách hiệu quả :ở đây và thứ hai, nó đặt dấu tách bản ghi đầu ra ( $\) thành bất kỳ giá trị bát phân hoặc hex nào được đưa ra ( 012is \n). Nếu $\được xác định, nó sẽ được thêm vào cuối mỗi printcuộc gọi, vì vậy điều này sẽ dẫn đến một dòng mới được thêm vào mỗi cuộc gọi print.

Ý -pechí p rint mỗi dòng đầu vào sau khi áp dụng tập lệnh được đưa ra bởi -e. Ở đây không có kịch bản vì tất cả công việc được thực hiện bằng các cờ tùy chọn như được mô tả ở trên!


Một lớp lót của bạn không đủ tối nghĩa! Đây là phiên bản không có mã để chuyển đổi -e thực thi vì các công tắc khác xử lý mọi thứ : perl -0x3a -l012 -pe '' <<<$PATH. Giải thích: -0đặt dấu tách bản ghi đầu vào (được chỉ định trong ký hiệu hex / bát phân, x3A là dấu hai chấm), -lthực hiện hai điều: 1) nó phân tách dấu tách bản ghi đầu vào, 2) nó đặt dấu tách bản ghi đầu ra nếu được chỉ định (theo ký hiệu bát phân , 012 là một dòng mới). Một -pvòng lặp in ra giá trị của $ _, sẽ là mỗi dòng được đọc.
7stud

Cũng lưu ý rằng các ví dụ của bạn sử dụng -Fcó thể loại bỏ các cờ -a-ncờ, vì -F tự động bật chúng perl -F: -e 'print(join "\n", @F);' <<<$PATH. Xem perlrun . Ví dụ tốt đẹp.
7stud

@ 7stud wow, đó thực sự là một loại tuyệt vời, cảm ơn! Bị đánh cắp một cách đáng xấu hổ và thêm vào câu trả lời của tôi (Tôi cho rằng bạn không phiền, cứ tự nhiên đăng nó như một câu trả lời và tôi sẽ xóa nó đi). Và cảm ơn -Fthông tin. Tôi đã sử dụng -Fkết hợp với -annhiều năm, tôi chưa bao giờ nhận ra cái này ngụ ý những cái khác. Nhân tiện, tôi thấy Serg đã đề cập đến Code Golf , nhưng tôi nghĩ bạn cũng sẽ thích Unix & Linux nếu bạn thích loại này.
terdon

Này cảm ơn nhé. Một cách làm rõ về tuyên bố này: Cuối cùng, -lcũng thêm dấu phân tách bản ghi đầu ra được cung cấp vào cuối mỗi lệnh gọi in. Trong thực tế, in luôn thêm dấu tách bản ghi đầu ra $/, vào cuối chuỗi - nếu phân tách bản ghi đầu ra được xác định. Theo mặc định, nó là undef. Vì vậy, -ljus đặt $/và điều đó khiến cho việc in thêm dòng mới vào cuối chuỗi.
7

Tôi cho rằng bạn không phiền - Không hề. :)
7stud

6

Trong câu trả lời này:

  1. C
  2. Con trăn
  3. Hồng ngọc
  4. Thay thế awk

1. C

Vì tất cả các ngôn ngữ kịch bản đã được sử dụng, tôi sẽ sử dụng C. Việc lấy các biến môi trường có get_env()chức năng khá dễ dàng (xem tài liệu Thư viện GNU C ). Phần còn lại chỉ đơn giản là thao tác nhân vật

bash-4.3$ cat get_path.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    char *path = getenv("PATH");
    int length = strlen(path) -1;
    for(int i=0;i<=length;i++){
        if (path[i] == ':')
            path[i] = '\n';
        printf("%c",path[i]);
    }
    printf("\n");
    return 0;
}
bash-4.3$ gcc get_path.c
bash-4.3$ ./a.out 
/home/xieerqi/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/opt/microchip/xc16/v1.25/bin
/opt/microchip/xc32/v1.40/bin
/opt/microchip/xc8/v1.35/bin
/home/xieerqi/bin
/home/xieerqi/bin/sh

2. Con trăn

Nhưng cũng bởi vì "tại sao không", đây là phiên bản python thay thế thông qua các đối số dòng lệnh sys.argv

python -c 'import sys; print "\n".join(sys.argv[1].split(":"))' "$PATH"

3. Ruby

Ruby không đi kèm với Ubuntu theo mặc định, không giống như trình biên dịch C và trình thông dịch Python, nhưng nếu bạn thấy mình sử dụng nó, giải pháp trong Ruby sẽ là:

ruby -ne 'puts $_.split(":")' <<< "$PATH"

Theo đề xuất của 7stud (Cảm ơn bạn rất nhiều!) Trong các bình luận , điều này cũng có thể được rút ngắn với

ruby -F: -ane 'puts $F' <<<$PATH

cách này

ruby -0072 -ne 'puts chomp' <<<$PATH

4. Thay thế awk

Chúng ta có thể sử dụng split()chức năng để chia dòng đọc thành mảng và sử dụng for-eachvòng lặp để in ra từng mục trên dòng riêng biệt.

awk '{split($0,arr,":"); for(var in arr) print arr[var]}' <<< $PATH

1
Ví dụ ruby ​​đẹp. putstự động in các phần tử của một mảng trên các dòng riêng biệt! Bạn cũng có thể làm cho các công tắc thực hiện phân tách: ruby -F: -ane 'puts $F' <<<$PATH Giải thích: -Fđặt $;thành ký tự được chỉ định, là dấu tách mặc định được sử dụng bởi String :: split ($; có giá trị mặc định là nil, phân tách trên khoảng trắng). -agọi $ _. split, trong đó $ _ là một dòng được đọc bằng cách sử dụng got ()) và gán mảng kết quả cho $F.
7

@ 7stud này, cảm ơn! :) Không biết có -Fcờ - Tôi mới bắt đầu với Ruby, nên làm mọi thứ hơi thô thiển.
Sergiy Kolodyazhnyy

Không, đây là thứ tối nghĩa. Một lớp lót của bạn rất dễ đọc, và sự rõ ràng nên luôn luôn vui vẻ.
7

Hah Tôi đã tìm ra một cái ngắn hơn : ruby -0072 -ne 'puts chomp' <<<$PATH. Giải thích: -0đặt dấu tách bản ghi đầu vào (chỉ định một ký tự ở định dạng bát phân; 072 là dấu hai chấm). Ruby sử dụng $ _ theo cách tương tự như Perl. Phương pháp được () (được sử dụng trong -nvòng lặp) bộ $ _ với dòng dòng đó của đọc. Và chomp()không có arg, chomps $ _. Tôi vẫn thích bạn tốt hơn. :)
7stud

@ 7stud thực sự, cái bạn đã đăng trước đó, với -Fcờ, ngắn hơn. Nếu bạn làm điều echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c đó cho tôi biết đó là 271, byte, nhưng cái có số bát phân là 276. Tất nhiên, đó là cho toàn bộ lệnh, nếu chúng ta chỉ xem xét bản thân mã puts $Fthì ngắn hơn rõ ràng. :) Nhân tiện, bạn có biết về Code Golf không? Đây là trang web cho các giải pháp để lập trình các câu đố với số byte ngắn nhất. Có một câu hỏi liên quan đến câu hỏi này: codegolf.stackexchange.com/q/96334/55572
Sergiy Kolodyazhnyy

5

Có lẽ cách duy nhất chưa được đề cập là cách tôi đã sử dụng nó trong nhiều năm:

echo $PATH | tr ":" "\n"

vì vậy, trong .profile hoặc .bash_profile của bạn hoặc bất cứ điều gì, bạn có thể thêm:

alias path='echo $PATH | tr ":" "\n"'


1
Câu trả lời này đã đề cập đến nó rồi ..
heemayl

Vâng, nhưng tôi thích đề xuất cho bí danh.
7stud

4

Chúng ta cần thêm Java!

public class GetPathByLine {
    public static void main(String[] args) {
        for (String p : System.getenv("PATH").split(":")) {
            System.out.println(p);
        }
    }
}

Lưu cái này vào GetPathByLine.javavà biên dịch bằng cách sử dụng:

javac GetPathByLine.java

Chạy với:

java GetPathByLine

┌─[17:06:55]─[kazwolfe@BlackHawk]
└──> ~ $ cat GetPathByLine.java 
public class GetPathByLine {
    public static void main(String[] args) {
        for (String p : System.getenv("PATH").split(":")) {
            System.out.println(p);
        }
    }
}
┌─[17:06:58]─[kazwolfe@BlackHawk]
└──> ~ $ javac GetPathByLine.java 
┌─[17:07:02]─[kazwolfe@BlackHawk]
└──> ~ $ java GetPathByLine 
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin

Wow đây là quá mức cần thiết. Bạn có thể làm điều này trong một dòng trong Python 3:python3 -c "import os; [print(p) for p in os.getenv('PATH').split(':')]"
wjandrea

1
@wjandrea Đó là điểm chính! : D
Kaz Wolfe

3

Qua awk.

echo $PATH | awk -F: '{for(i=1;i<=NF;i++)print $i}'

Qua trăn.

$ echo $PATH | python3 -c 'import fileinput
for line in fileinput.input():
    for i in line.split(":"):
        print(i)'

Lưu ý rằng thụt là rất quan trọng trong python.


echo $PATH | awk '{gsub(/\:/,"\n");print}'
Awk

Tôi không chắc tại sao bạn lại bận tâm fileinputkhi bạn chỉ có thể sử dụng input:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
wjandrea

2

Tôi sử dụng "Bash Path Function" của Stephen Colly (xem bài viết của ông trên Tạp chí Linux ). Nó cho phép tôi sử dụng "danh sách phân tách dấu hai chấm" làm kiểu dữ liệu trong lập trình shell. Ví dụ: tôi có thể tạo một danh sách tất cả các thư mục trong thư mục hiện tại bằng cách:

dirs="";for i in * ; do if [ -d $i ] ; then addpath -p dirs $i; fi; done  

Sau đó, listpath -p dirstạo ra một danh sách.


2

Giải thích cho câu trả lời @Cyrus

echo "${PATH//:/$'\n'}"

Ghi chú:

Trích dẫn ANSI-C - nó giải thích $ 'some \ ntext'

Mở rộng tham số Shell - nó giải thích $ {tham số / mẫu / chuỗi}, Nếu mẫu bắt đầu bằng '/', tất cả các kết quả khớp của mẫu được thay thế bằng chuỗi.

Vì vậy chúng tôi có:

  1. một mẫu /: bắt đầu bằng '/' để thay thế tất cả các kết quả khớp
  2. một chuỗi $ '\ n' được trích dẫn với sự co lại của $ 'anytext' để xử lý ký hiệu dòng mới (\ n).

1

Một cách khác của AWK là coi mỗi thư mục là một bản ghi riêng , thay vì một trường riêng biệt .

awk 'BEGIN{RS=":"} {print $0}' <<<"$PATH"

Tôi thấy cú pháp đó đặc biệt trực quan. Nhưng, nếu bạn thích, bạn có thể rút ngắn nó bằng cách làm print $0ẩn (đó là hành động mặc định và 1đánh giá là đúng, khiến nó được thực hiện cho mọi dòng):

awk 'BEGIN{RS=":"} 1' <<<"$PATH"

Dấu tách bản ghi đầu vào và đầu ra mặc định của AWK là dòng mới (ngắt dòng). Bằng cách đặt dấu tách bản ghi đầu vào ( RS) thành :trước khi đọc đầu vào, AWK sẽ tự động phân tích cú pháp dấu hai chấm được phân định $PATHthành các tên thư mục cấu thành của nó. AWK mở rộng $0đến từng bản ghi, dòng mới vẫn là dấu phân tách bản ghi đầu ra và không cần lặp hoặc gsubcần thiết.

ek@Io:~$ echo "$PATH"
/home/ek/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ek@Io:~$ awk 'BEGIN{RS=":"} {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

AWK thường được sử dụng để phân tích các bản ghi thành các trường riêng biệt, nhưng không cần điều đó chỉ để xây dựng một danh sách các tên thư mục.

Điều này hoạt động ngay cả đối với đầu vào có khoảng trống (khoảng trắng và tab), thậm chí nhiều khoảng trống liên tiếp:

ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}' <<<$'ab\t\t c:de    fg:h'
ab               c
de    fg
h

Đó là, trừ khi bạn khiến AWK xây dựng lại bản ghi (xem bên dưới), không có vấn đề gì để có khoảng trắng hoặc tab (dấu phân cách trường mặc định) trong đầu vào. Bạn PATHcó lẽ không chứa khoảng trắng trên một hệ thống Ubuntu, nhưng nếu có, đây vẫn sẽ làm việc.


Điều đáng nói, như một lưu ý phụ, rằng khả năng diễn giải bản ghi của AWK là một tập hợp các trường trở nên hữu ích cho vấn đề liên quan đến việc xây dựng bảng các thành phần thư mục :

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

$1=$1Nhiệm vụ gây tò mò phục vụ mục đích buộc AWK phải xây dựng lại hồ sơ .

(Điều này có lẽ hữu ích hơn cho các trường hợp xử lý bổ sung được thực hiện trên các thành phần, so với ví dụ chính xác được hiển thị chỉ đơn giản là in bảng.)



0

Cách hiển thị các đường dẫn trong $ PATH riêng

Đây là những cách ưa thích của tôi để làm điều này dựa trên các trường hợp sử dụng tương ứng và mối quan tâm của tôi về khả năng tương thích và sử dụng tài nguyên.

tr

Đầu tiên, nếu bạn cần một giải pháp nhanh chóng, dễ nhớ và dễ đọc, chỉ cần lặp lại PATHvà chuyển nó sang dịch ( tr) để biến dấu hai chấm thành dòng mới:

echo $PATH | tr : "\n"

Nó có nhược điểm của việc sử dụng hai quy trình vì đường ống, nhưng nếu chúng ta chỉ hack trong một thiết bị đầu cuối, chúng ta có thực sự quan tâm đến điều đó không?

Mở rộng tham số shell của Bash

Nếu bạn muốn một giải pháp khá lâu dài trong .bashrcsử dụng tương tác của mình , bạn có thể đặt bí danh cho lệnh sau path, nhưng khả năng đọc của giải pháp này là đáng nghi ngờ:

alias path="echo \"${PATH//:/$'\n'}\""

Nếu mẫu bắt đầu bằng '/', tất cả các kết quả khớp của mẫu được thay thế bằng chuỗi. Thông thường chỉ có trận đấu đầu tiên được thay thế.

Lệnh trên thay thế dấu hai chấm bằng dòng mới bằng cách sử dụng Mở rộng tham số Shell của Bash :

${parameter/pattern/string}

Để giải thích nó:

          # v--v---------delimiters, a'la sed
echo "${PATH//:/$'\n'}"
          #  ^^ ^^^^^----string, $ required to get newline character.
          #   \----------pattern, / required to substitute for *every* :.

Chúc may mắn nhớ điều này khi bạn chỉ hack trên dòng lệnh, mặc dù bạn không có bí danh.

IFS, được thử nghiệm trong Bash và Dash

Ngoài ra, một cách tiếp cận tương thích chéo, dễ đọc và dễ hiểu mà không dựa vào bất cứ thứ gì ngoài vỏ được sử dụng chức năng sau (tôi đề nghị trong của bạn .bashrc.)

Hàm sau tạm thời biến Dấu tách trường nội bộ (hoặc Đầu vào) (IFS) thành dấu hai chấm và khi một mảng được đưa vào printf, nó sẽ thực thi cho đến khi mảng được sử dụng hết:

path () {
    local IFS=:
    printf "%s\n" ${PATH}
    }

Phương pháp này tạo ra chức năng , IFSprintfđược quy định của posix, vì vậy nó sẽ làm việc trong hầu hết các posix giống như vỏ (đặc biệt là Dash, mà Ubuntu thường bí danh như sh).

Con trăn

Bạn có nên sử dụng Python cho việc này? Bạn có thể. Đây là lệnh Python ngắn nhất tôi có thể nghĩ ra cho việc này:

python -c "print('\n'.join('${PATH}'.split(':')))"

hoặc chỉ Python 3 (và có lẽ dễ đọc hơn?):

python3 -c "print(*'${PATH}'.split(':'), sep='\n')"

Chúng cũng hoạt động trong mọi môi trường shell thông thường, miễn là bạn có Python.


0

Giải pháp này đơn giản hơn các giải pháp Java , C , goawk :

$ LPATH=$PATH wine cmd /c echo %LPATH::=$'\n'% 2> /dev/null
/usr/local/bin
/usr/local/sbin
/usr/bin
/usr/sbin

Đây là một khả năng tuyệt vời khác:

$ jrunscript -classpath /usr/share/java/bsh.jar -e 'print(java.lang.System.getenv("PATH").replaceAll(":","\n"))'
/usr/local/bin
/usr/local/sbin
/usr/bin
/usr/sbin

Điều này sẽ yêu cầu một số phụ thuộc được cài đặt:

sudo apt-get install openjdk-8-jdk-headless bsh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.