ฉันไม่สามารถหาวิธีแสดงรายการเส้นทางต่าง ๆ$PATH
แยกจากกันเพื่อให้พวกเขามีลักษณะดังนี้:
/bin
/usr/bin
/usr/local/bin
เป็นต้น
ไม่มีใครรู้ว่าตัวแปรที่ถูกต้องสำหรับเรื่องนี้?
ฉันไม่สามารถหาวิธีแสดงรายการเส้นทางต่าง ๆ$PATH
แยกจากกันเพื่อให้พวกเขามีลักษณะดังนี้:
/bin
/usr/bin
/usr/local/bin
เป็นต้น
ไม่มีใครรู้ว่าตัวแปรที่ถูกต้องสำหรับเรื่องนี้?
คำตอบ:
ลองsed
:
$ sed 's/:/\n/g' <<< "$PATH"
หรือtr
:
$ tr ':' '\n' <<< "$PATH"
หรือpython
:
$ python2 -c "import os; print os.environ['PATH'].replace(':', '\n')"
นี่คือทั้งหมดข้างต้นจะแทนเหตุการณ์ที่เกิดขึ้นทั้งหมดที่มีเส้นใหม่:
\n
python -c 'import sys;print sys.argv[1].replace(":","\n")' $PATH
python -c "print r'$PATH'.replace(':', '\n')"
(ใช้สตริงดิบในกรณีที่แบ็กสแลช)
tr
ทำงานได้สำหรับฉัน (บน mac, btw) ขอบคุณ
.bash_profile
เพิ่มมันเช่นนี้alias path='tr ":" "\n" <<< "$PATH"'
ใช้การขยายพารามิเตอร์ของ bash :
echo "${PATH//:/$'\n'}"
แทนที่ทั้งหมดนี้:
ใน$PATH
โดยการขึ้นบรรทัดใหม่ ( \n
) และพิมพ์ผล เนื้อหาของ$PATH
ยังคงไม่เปลี่ยนแปลง
หากคุณต้องการแทนที่ครั้งแรก:
ให้ลบเครื่องหมายทับที่สอง:echo -e "${PATH/:/\n}"
${parameter/pattern/string}
ใช้ IFS:
(set -f; IFS=:; printf "%s\n" $PATH)
IFS
ถือตัวละครที่ทุบตีไม่แยกดังนั้นIFS
ด้วย:
ทำให้ทุบตีแยกการขยายตัวของบน$PATH
วนรอบอาร์กิวเมนต์ของสตริงรูปแบบจนกว่าอาร์กิวเมนต์จะหมดลง เราจำเป็นต้องปิดการใช้งาน globbing (การขยายไวด์การ์ด) โดยใช้เพื่อให้ไวด์การ์ดในชื่อไดเรกทอรี PATH ไม่ได้รับการขยาย:
printf
set -f
การใช้xargs
:
xargs -n1 -d: <<< $PATH
จาก man xargs
-n max-args
Use at most max-args arguments per command line.
-d delim
Input items are terminated by the specified character.
echo $PATH | xargs -n1 -d: echo
ซ้ำซ้อนหรือไม่สำคัญ?
echo $PATH | xargs -n1 -d:
จะทำสิ่งเดียวกันสำหรับคุณ แต่คุณจะใช้อีกหนึ่งเชลล์ คนแรกจะประเมินecho $PATH
และท่อส่งออกไปยังเปลือกถัดไปเพื่อทำส่วนที่เหลือ
นี่คือสิ่งที่เทียบเท่าใน 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
นี่คือแนวทางอีกสองสามข้อ ฉันใช้PATH
ไดเรกทอรีที่มีเครื่องหมายแบ็กสแลชช่องว่างและแม้แต่บรรทัดใหม่เพื่อแสดงว่าพวกเขาควรทำงานกับทุกสิ่ง (ยกเว้นcut
ที่ไม่ได้อยู่ในบรรทัดใหม่):
$ echo "$PATH"
/bin:usr/bin/:/usr/local/bin:/some\ horrible thing:/even
new lines
บางวิธี Perl:
$ perl -pe 's/:/\n/g' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
-p
หมายถึง "พิมพ์บรรทัดทุกท่านหลังจากการใช้สคริปต์ที่กำหนดโดย-e
" สคริปต์กำลังใช้ตัวดำเนินการทดแทน ( s/oldnew/
) เพื่อแทนที่ทั้งหมด:
ด้วยบรรทัดใหม่
$ perl -lne 'print for split /:/' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
-l
เพิ่มขึ้นบรรทัดใหม่ให้กับแต่ละprint
โทร ที่นี่สคริปต์แยกอินพุตของมัน:
แล้ววนซ้ำแต่ละองค์ประกอบแยกแล้วพิมพ์ออกมา
$ perl -F: -ane '$"="\n";print "@F"' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
-a
ทำให้perl
ทำตัวเหมือนawk
มันจะแยกแต่ละเส้นที่นำเข้าที่มีต่อตัวละครที่ได้รับจาก-F
(ดังนั้น:
ที่นี่) @F
และบันทึกผลในอาร์เรย์ The $"
เป็นตัวแปร Perl พิเศษคือ "list separator" ซึ่งมีการพิมพ์ค่าระหว่างองค์ประกอบแต่ละรายการของรายการที่พิมพ์ ดังนั้นการตั้งค่าให้ขึ้นบรรทัดใหม่จะทำให้print @list
พิมพ์แต่ละองค์ประกอบของ@list
และจากนั้นขึ้นบรรทัดใหม่ @F
นี่เรากำลังใช้มันในการพิมพ์
$ perl -F: -ane 'print join "\n", @F' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
ความคิดเช่นเดียวกับข้างต้นเพียงน้อย golfed แทนที่จะใช้$"
เรากำลังjoin
นำอาร์เรย์ขึ้นบรรทัดใหม่แล้วพิมพ์อย่างชัดเจน
เรียบง่ายgrep
ด้วย PCRE magic:
$ grep -oP '(^|:)\K[^:]+' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
-o
ทำให้grep
พิมพ์เฉพาะส่วนการจับคู่ของแต่ละบรรทัดเพื่อให้การแข่งขันแต่ละครั้งจะพิมพ์อยู่บนบรรทัดที่แยกต่างหาก -P
ช่วยนิพจน์ปกติ Perl เข้ากันได้ (PCRE) regex กำลังค้นหาส่วนขยายของ non- :
( [^:]+
) ที่ตามหลังจุดเริ่มต้นของบรรทัด ( ^
) หรือ:
อักขระ นี่\K
เป็นเคล็ดลับ PCRE ที่หมายถึง "ทิ้งสิ่งใดที่ตรงกับจุดนี้" และใช้ที่นี่เพื่อหลีกเลี่ยงการพิมพ์:
เช่นกัน
และcut
วิธีแก้ปัญหา (อันนี้ล้มเหลวในการขึ้นบรรทัดใหม่ แต่สามารถจัดการกับแบ็กสแลชและช่องว่าง):
$ cut -d: -f 1- --output-delimiter=$'\n' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
ตัวเลือกที่ใช้เป็น-d:
ที่กำหนดคั่นป้อนข้อมูลเพื่อ:
, -f 1-
ซึ่งหมายถึงการพิมพ์ทุกสาขา (ตั้งแต่วันที่ 1 ถึงปลาย) และ--output-delimiter=$'\n'
ซึ่งชุดที่ดี, ตัวคั่นเอาท์พุท $'\n'
เป็นANSI C quotingและเป็นวิธีที่จะพิมพ์ตัวอักษรขึ้นบรรทัดใหม่ในเปลือก
ในตัวอย่างข้างต้นทั้งหมดฉันใช้ตัวดำเนินการstring ( <<<
) ของ shell ( ) และ shell อื่น ๆ บางตัว) เพื่อส่งผ่านสตริงเป็นอินพุตไปยังโปรแกรม ดังนั้นจะเทียบเท่ากับcommand <<<"foo"
echo -n "foo" | command
โปรดทราบว่าฉันมักจะพูด"$PATH"
โดยไม่ต้องพูดราคาเปลือกจะกินตัวละครขึ้นบรรทัดใหม่
@ 7studให้แนวทางอื่นในความคิดเห็นที่ดีเกินไปที่จะไม่รวม:
$ perl -0x3a -l012 -pe '' <<<"$PATH"
ว่าสิ่งที่เรียกว่าการเล่นกอล์ฟ -0
ระบุคั่นบันทึกการป้อนข้อมูลเป็นฐานแปดหรือเลขฐานสิบหกจำนวน นี่คือสิ่งที่กำหนด "บรรทัด" และค่าเริ่มต้นของมันคือ\n
อักขระขึ้นบรรทัดใหม่ นี่เรากำลังตั้งไป:
ซึ่งเป็นx3a
เลขฐานสิบหก (ลองprintf '\x3a\n'
) -l
ไม่สามสิ่ง ครั้งแรกก็เอาบันทึกการป้อนข้อมูลแยก ( $/
) จากจุดสิ้นสุดของแต่ละสายได้อย่างมีประสิทธิภาพลบ:
ที่นี่และครั้งที่สองมันชุดบันทึกเอาท์พุทคั่น ( $\
) เพื่อสิ่งที่ฐานแปดหรือค่า hex ก็จะได้รับ ( 012
เป็น\n
) หาก$\
มีการกำหนดจะถูกเพิ่มลงในตอนท้ายของการprint
โทรแต่ละครั้งดังนั้นสิ่งนี้จะส่งผลให้มีการขึ้นบรรทัดใหม่ต่อท้ายแต่ละการprint
เรียก
-pe
ประสงค์พี rint -e
สายการป้อนข้อมูลแต่ละหลังจากการใช้สคริปต์ที่กำหนดโดย ที่นี่ไม่มีสคริปต์เนื่องจากงานทั้งหมดทำโดยตัวเลือกการตั้งค่าสถานะตามที่อธิบายไว้ข้างต้น!
perl -0x3a -l012 -pe '' <<<$PATH
จัดการทุกอย่างไม่มี: คำอธิบาย: -0
ตั้งค่าตัวคั่นเรคคอร์ดอินพุต (ระบุไว้ในรูปแบบเลขฐานสิบหก / เลขฐานแปด, x3A เป็นโคลอน) -l
ทำสองสิ่ง: 1) มันจะแยกตัวคั่นเร็กคอร์ดอินพุต 2) ตั้งค่าตัวคั่นเร็กคอร์ดเอาท์พุทหากมีการระบุไว้ , 012 เป็นบรรทัดใหม่) การ-p
วนซ้ำพิมพ์ค่า $ _ ซึ่งจะเป็นแต่ละบรรทัดที่อ่านมา
-F
สามารถกำจัด-a
และ-n
ธงเป็น -F perl -F: -e 'print(join "\n", @F);' <<<$PATH
เปลี่ยนผู้ที่อยู่โดยอัตโนมัติ: ดูperlrun ตัวอย่างที่ดี
-F
ข้อมูล ฉันใช้-F
ร่วมกับ-an
มานานหลายปีฉันไม่เคยรู้เลยว่าคนอื่น ๆ อย่างไรก็ตามฉันเห็น Serg พูดถึงCode Golfแต่ฉันคิดว่าคุณจะเพลิดเพลินกับUnix & Linuxเช่นกันหากคุณชอบสิ่งนี้
-l
ก็เพิ่มตัวคั่นเร็กคอร์ดเอาท์พุทที่กำหนดไว้ที่ส่วนท้ายของการเรียกใช้การพิมพ์แต่ละครั้ง ในความเป็นจริงการพิมพ์จะเพิ่มตัวคั่นเร็กคอร์ดเอาท์พุทเสมอ$/
ไปยังจุดสิ้นสุดของสตริง - หากมีการกำหนดตัวคั่นเร็กคอร์ดเอาท์พุท โดยค่าเริ่มต้นมันเป็น undef ดังนั้น-l
jus จึงตั้งค่า$/
และทำให้การพิมพ์เพิ่มบรรทัดใหม่ไปยังจุดสิ้นสุดของสตริง
เนื่องจากภาษาสคริปต์ทั้งหมดได้ถูกใช้ไปแล้วฉันจะไปกับ C. มันค่อนข้างง่ายที่จะรับตัวแปรสภาพแวดล้อมพร้อมget_env()
ฟังก์ชั่น (ดูเอกสารประกอบ GNU C Library ) ส่วนที่เหลือเป็นเพียงการจัดการตัวละคร
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
แต่ก็เป็นเพราะ "ทำไมไม่" นี่เป็นเวอร์ชั่นไพ ธ อนอื่น ๆ ผ่านอาร์กิวเมนต์บรรทัดคำสั่ง sys.argv
python -c 'import sys; print "\n".join(sys.argv[1].split(":"))' "$PATH"
Ruby ไม่ได้มาพร้อมกับ Ubuntu โดยค่าเริ่มต้นซึ่งแตกต่างจาก C compiler และ Python interpreter แต่ถ้าคุณพบว่าตัวเองกำลังใช้อยู่คำตอบใน Ruby ก็คือ:
ruby -ne 'puts $_.split(":")' <<< "$PATH"
ตามที่แนะนำโดย 7stud (ขอบคุณมาก ๆ !) ในความคิดเห็นสิ่งนี้สามารถย่อให้สั้นลงได้
ruby -F: -ane 'puts $F' <<<$PATH
และด้วยวิธีนี้
ruby -0072 -ne 'puts chomp' <<<$PATH
เราสามารถใช้split()
ฟังก์ชั่นเพื่อแยกบรรทัดที่อ่านเข้าไปในอาร์เรย์และใช้การfor-each
วนซ้ำเพื่อพิมพ์แต่ละรายการในบรรทัดแยกกัน
awk '{split($0,arr,":"); for(var in arr) print arr[var]}' <<< $PATH
puts
พิมพ์องค์ประกอบของอาร์เรย์โดยอัตโนมัติในบรรทัดแยกกัน! นอกจากนี้คุณยังสามารถทำให้สวิตช์ทำการแยก: ruby -F: -ane 'puts $F' <<<$PATH
คำอธิบาย: -F
ตั้งค่า$;
เป็นอักขระที่ระบุซึ่งเป็นตัวคั่นเริ่มต้นที่ใช้โดย String :: split ($; มีค่าเริ่มต้นของศูนย์ซึ่งแยกบนช่องว่าง) -a
เรียก _ $. แยกที่ $ _ เป็นสายอ่านในการใช้ที่ได้รับ ()) $F
และกำหนดอาร์เรย์ที่มีผลต่อการ
-F
ธง - ฉันเพิ่งเริ่มต้นด้วย Ruby ดังนั้นการทำสิ่งที่ค่อนข้างหยาบ
ruby -0072 -ne 'puts chomp' <<<$PATH
. คำอธิบาย: -0
ตั้งค่าตัวคั่นเร็กคอร์ดอินพุต (ระบุอักขระในรูปแบบฐานแปด; 072 เป็นโคลอน) Ruby ใช้ $ _ ในรูปแบบที่คล้ายกับ Perl เมธอด gets () (ใช้ใน-n
ลูป) ตั้งค่า $ _ เป็นบรรทัดปัจจุบันที่อ่านมาและchomp()
ไม่มี arg, chomps $ _ ฉันยังคงชอบคุณดีกว่า :)
-F
ตั้งค่าสถานะจะสั้นกว่า ถ้าคุณecho "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c
บอกฉันว่ามันคือ 271 ไบต์ แต่สิ่งที่มีเลขฐานแปดคือ 276 นั่นคือสำหรับคำสั่งทั้งหมดแน่นอนถ้าเราพิจารณาเฉพาะรหัสตัวเอง puts $F
จะสั้นกว่าอย่างชัดเจน :) ยังไงคุณรู้เกี่ยวกับCode Golf ? เป็นเว็บไซต์สำหรับการแก้ปริศนาการเขียนโปรแกรมด้วยจำนวนไบต์ที่สั้นที่สุด มีคำถามเกี่ยวกับคำถามนี้: codegolf.stackexchange.com/q/96334/55572
อาจเป็นวิธีเดียวที่ไม่ได้กล่าวถึงคือวิธีที่ฉันใช้มันมาหลายปี:
echo $PATH | tr ":" "\n"
ดังนั้นใน. profile หรือ. bash_profile หรืออะไรก็ตามคุณสามารถเพิ่ม:
alias path='echo $PATH | tr ":" "\n"'
เราต้องการ Java เพิ่มเติม!
public class GetPathByLine {
public static void main(String[] args) {
for (String p : System.getenv("PATH").split(":")) {
System.out.println(p);
}
}
}
บันทึกสิ่งนี้เป็นGetPathByLine.java
และรวบรวมโดยใช้:
javac GetPathByLine.java
ทำงานด้วย:
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
python3 -c "import os; [print(p) for p in os.getenv('PATH').split(':')]"
ผ่าน awk
echo $PATH | awk -F: '{for(i=1;i<=NF;i++)print $i}'
ผ่านหลาม
$ echo $PATH | python3 -c 'import fileinput
for line in fileinput.input():
for i in line.split(":"):
print(i)'
โปรดทราบว่าการเยื้องมีความสำคัญมากในหลาม
echo $PATH | awk '{gsub(/\:/,"\n");print}'
fileinput
เมื่อคุณสามารถใช้input
:python3 -c 'print(*input().split(":"), sep="\n")' <<< "$PATH"
ฉันใช้ "Bash Path Function" ของ Stephen Collyer (ดูบทความของเขาใน Linux Journal ) มันอนุญาตให้ฉันใช้ "รายการที่คั่นด้วยโคลอน" เป็นประเภทข้อมูลในการเขียนโปรแกรมเชลล์ ตัวอย่างเช่นฉันสามารถสร้างรายชื่อของไดเรกทอรีทั้งหมดในไดเรกทอรีปัจจุบันโดย:
dirs="";for i in * ; do if [ -d $i ] ; then addpath -p dirs $i; fi; done
จากนั้นlistpath -p dirs
สร้างรายการ
คำอธิบายสำหรับ @Cyrus คำตอบ
echo "${PATH//:/$'\n'}"
หมายเหตุ:
ANSI-C Quoting - มันอธิบาย $ 'some \ ntext'
การขยายพารามิเตอร์เชลล์ - มันอธิบาย $ {พารามิเตอร์ / รูปแบบ / สตริง}, หากรูปแบบเริ่มต้นด้วย '/' การจับคู่รูปแบบทั้งหมดจะถูกแทนที่ด้วยสตริง
ดังนั้นเราจึงมี:
วิธี AWK อีกประการหนึ่งคือการรักษาแต่ละ directory เป็นแยกบันทึกมากกว่าที่จะเป็นแยกฟิลด์
awk 'BEGIN{RS=":"} {print $0}' <<<"$PATH"
ฉันพบว่าใช้งานง่ายยิ่งขึ้น แต่ถ้าคุณชอบคุณสามารถย่อให้สั้นลงได้โดยการบอกเป็นprint $0
นัย (เป็นการกระทำที่เป็นค่าเริ่มต้นและ1
ประเมินผลเป็นจริงทำให้ต้องทำทุกบรรทัด):
awk 'BEGIN{RS=":"} 1' <<<"$PATH"
ตัวคั่นอินพุตและเอาต์พุตเริ่มต้นของ AWK คือบรรทัดใหม่ (ตัวแบ่งบรรทัด) ด้วยการตั้งค่าตัวคั่นเรคคอร์ดอินพุต ( RS
) เป็น:
ก่อนอ่านอินพุต AWK จะวิเคราะห์คำที่คั่นด้วยโคลอนโดยอัตโนมัติ$PATH
ในชื่อไดเรกทอรีที่ประกอบด้วย AWK ขยาย$0
ไปยังแต่ละระเบียนทั้งหมดขึ้นบรรทัดใหม่ยังคงเป็นตัวแยกระเบียนผลลัพธ์และไม่gsub
จำเป็นต้องวนซ้ำหรือ
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 มักจะใช้ในการแยกวิเคราะห์บันทึกลงในเขตข้อมูลที่แยกจากกัน แต่ไม่จำเป็นต้องสร้างรายชื่อไดเรกทอรี
วิธีนี้ใช้ได้แม้กับอินพุตที่มีช่องว่าง (ช่องว่างและแท็บ) แม้ช่องว่างหลายช่องติดต่อกัน:
ek@Io:~$ awk 'BEGIN{RS=":"} {print $0}' <<<$'ab\t\t c:de fg:h'
ab c
de fg
h
นั่นคือยกเว้นว่าคุณทำให้ AWK สร้างบันทึกใหม่ (ดูด้านล่าง) จะไม่มีปัญหาในการมีช่องว่างหรือแท็บ (ตัวคั่นเขตข้อมูลเริ่มต้น) ในอินพุต คุณPATH
อาจไม่มีที่ว่างในระบบ Ubuntu แต่ถ้าเป็นเช่นนั้นสิ่งนี้จะยังคงใช้งานได้
เป็นมูลค่าการกล่าวขวัญเป็นบันทึกด้านที่ AWK ความสามารถในการตีความบันทึกเป็นชุดของเขตข้อมูลจะเป็นประโยชน์สำหรับปัญหาที่เกี่ยวข้องกับการสร้างตารางขององค์ประกอบไดเรกทอรี:
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=$1
มอบหมายที่อยากรู้อยากเห็นมีวัตถุประสงค์เพื่อบังคับให้ AWK สร้างบันทึกใหม่
(นี่อาจเป็นประโยชน์มากกว่าสำหรับกรณีที่การประมวลผลเพิ่มเติมจะต้องทำในส่วนประกอบกว่าตัวอย่างที่แสดงให้เห็นเพียงพิมพ์ตาราง)
jq -Rr 'gsub(":";"\n")' <<<$PATH
วิธีแสดงเส้นทางใน $ PATH แยกกัน
นี่เป็นวิธีที่ฉันชอบในการทำสิ่งนี้โดยพิจารณาจากกรณีการใช้งานและข้อกังวลเกี่ยวกับความเข้ากันได้และการใช้ทรัพยากร
tr
ก่อนอื่นถ้าคุณต้องการวิธีแก้ปัญหาที่รวดเร็วง่ายต่อการจดจำและอ่านได้เพียงแค่ก้องPATH
และแปะมันเพื่อแปล ( tr
)เพื่อเปลี่ยน colons ให้เป็นบรรทัดใหม่:
echo $PATH | tr : "\n"
มีข้อเสียของการใช้สองกระบวนการเนื่องจากไปป์ แต่ถ้าเราแค่แฮ็คในเทอร์มินัลเราสนใจจริง ๆ หรือไม่
หากคุณต้องการโซลูชันที่ค่อนข้างถาวร.bashrc
สำหรับการใช้งานแบบโต้ตอบคุณสามารถนามแฝงคำสั่งต่อไปนี้path
แต่ความสามารถในการอ่านของโซลูชันนี้เป็นที่น่าสงสัย:
alias path="echo \"${PATH//:/$'\n'}\""
หากรูปแบบเริ่มต้นด้วย '/' การจับคู่รูปแบบทั้งหมดจะถูกแทนที่ด้วยสตริง โดยปกติจะมีการแข่งขันนัดแรกเท่านั้น
คำสั่งดังกล่าวจะแทนที่โคลอนด้วยการขึ้นบรรทัดใหม่โดยใช้การขยายพารามิเตอร์เชลล์ของ Bash :
${parameter/pattern/string}
เพื่ออธิบาย:
# v--v---------delimiters, a'la sed
echo "${PATH//:/$'\n'}"
# ^^ ^^^^^----string, $ required to get newline character.
# \----------pattern, / required to substitute for *every* :.
โชคดีที่จำสิ่งนี้ได้เมื่อคุณแฮ็คข้อมูลบรรทัดคำสั่งหากคุณยังไม่ได้ใช้นามแฝง
อีกวิธีหนึ่งคือวิธีที่เข้ากันได้ข้ามอ่านและเข้าใจได้อย่างเป็นธรรมที่ไม่พึ่งพาสิ่งอื่นใดนอกจากเชลล์ใช้ฟังก์ชั่นต่อไปนี้ (ฉันแนะนำในของคุณ.bashrc
)
ฟังก์ชั่นต่อไปนี้ทำให้ตัวคั่นฟิลด์ (หรืออินพุต) ภายใน (IFS) เป็นโคลอนชั่วคราวและเมื่ออาเรย์ถูกกำหนดให้printf
มันจะทำงานจนกว่าจะมีการใช้อาเรย์:
path () {
local IFS=:
printf "%s\n" ${PATH}
}
วิธีการนี้สร้างฟังก์ชั่น , IFS
และprintf
จะให้ตาม POSIX ดังนั้นจึงควรทำงานใน POSIX เหมือนเปลือกหอยมากที่สุด (โดยเฉพาะ Dash ซึ่ง Ubuntu มักจะเป็นนามแฝงsh
)
คุณควรใช้ Python สำหรับสิ่งนี้หรือไม่? คุณทำได้ นี่เป็นคำสั่ง Python ที่สั้นที่สุดที่ฉันสามารถนึกได้:
python -c "print('\n'.join('${PATH}'.split(':')))"
หรือ Python 3 เท่านั้น (และอาจอ่านง่ายขึ้น?):
python3 -c "print(*'${PATH}'.split(':'), sep='\n')"
สิ่งเหล่านี้ควรทำงานในสภาพแวดล้อมเชลล์ปกติเช่นกันตราบใดที่คุณมี Python
โซลูชันนี้ง่ายกว่าโซลูชันJava , C , goและawk :
$ LPATH=$PATH wine cmd /c echo %LPATH::=$'\n'% 2> /dev/null
/usr/local/bin
/usr/local/sbin
/usr/bin
/usr/sbin
นี่เป็นโอกาสที่ยอดเยี่ยมอีกอย่างหนึ่ง:
$ 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
สิ่งนี้จะต้องมีการติดตั้งการอ้างอิงบางอย่าง:
sudo apt-get install openjdk-8-jdk-headless bsh