다양한 경로를 $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
은 변경되지 않습니다.
first 만 바꾸려면 :
두 번째 슬래시를 제거하십시오.echo -e "${PATH/:/\n}"
${parameter/pattern/string}
IFS 사용 :
(set -f; IFS=:; printf "%s\n" $PATH)
IFS
bash가 분할하는 문자를 보유하므로 IFS
with :
는 bash가 $PATH
on 의 확장을 분할하게합니다 :
. printf
인수가 소진 될 때까지 형식 문자열에서 인수를 반복합니다. set -f
PATH 디렉토리 이름의 와일드 카드가 확장되지 않도록 사용하여 글 로빙 (와일드 카드 확장)을 비활성화해야합니다 .
사용 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
백 슬래시, 공백 및 줄 바꿈이 포함 된 with 디렉토리를 사용하여 줄 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
. 이것은 $"
특수한 Perl 변수 인 "목록 구분 기호"이며 값은 인쇄 된 목록의 각 요소 사이에 인쇄됩니다. 따라서 개행으로 설정하면 print @list
각 요소를 인쇄 @list
한 다음 개행 을 인쇄합니다 . 여기서는 인쇄에 사용하고 있습니다 @F
.
$ perl -F: -ane 'print join "\n", @F' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
위와 같은 아이디어, 덜 골프. 를 사용하는 대신 배열을 개행 $"
으로 명시 적으로 join
인쇄 한 다음 인쇄합니다.
grep
PCRE 매직으로 간단 하게 :
$ grep -oP '(^|:)\K[^:]+' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
-o
차종이 grep
일치하는 각이 한 줄에 인쇄되어 있으므로, 각 행의 정합 부를 인쇄. 는 -P
펄 호환 정규 표현식 (PCRE)를 할 수 있습니다. 정규식은 줄의 시작 부분 ( ) 또는 문자 뒤에 오는 비 :
( [^:]+
)가 아닌 부분을 찾고 있습니다. 는 수단 "폐기 것도이 시점 이전에 일치"및 인쇄를 방지하기 위해 여기에 사용하는 PCRE 트릭 뿐만 아니라. ^
:
\K
:
그리고 cut
해결책 (이것은 줄 바꿈에서는 실패하지만 백 슬래시와 공백을 다룰 수 있습니다) :
$ cut -d: -f 1- --output-delimiter=$'\n' <<<"$PATH"
/bin
usr/bin/
/usr/local/bin
/some\ horrible thing
/even
new lines
사용되는 옵션 -d:
은 입력 구분 기호를로 설정합니다. 즉 :
, -f 1-
모든 필드를 인쇄하고 (첫 번째에서 끝까지) --output-delimiter=$'\n'
출력 구분 기호를 설정합니다. 은 $'\n'
입니다 ANSI C가 인용 쉘에서 개행 문자를 인쇄하는 방법입니다.
위의 모든 예제에서 bash (및 다른 셸) here string ( <<<
) 연산자를 사용하여 문자열을 프로그램에 입력으로 전달합니다. 따라서 command <<<"foo"
와 같습니다 echo -n "foo" | command
. "$PATH"
따옴표없이 항상 따옴표를 인용 하고 있습니다. 쉘은 개행 문자를 먹었을 것입니다.
@ 7stud 는 주석 에 포함시키지 않는 것이 좋은 또 다른 접근법을 제시 했습니다.
$ perl -0x3a -l012 -pe '' <<<"$PATH"
이것이 골프 라고 알려진 것 입니다. 는 -0
진법 또는 16 진수로 입력 레코드 분리를 지정한다. 이것은 "라인"을 정의하고 기본 값은 무엇인가 \n
, 개행 문자. 여기, 우리는 그것을 설정하는 :
어떤 x3a
진수 (시도에서 printf '\x3a\n'
). 는 -l
세 가지를 않습니다. 첫째는 입력 레코드 분리 (제거하는 $/
각각의 단부에서) 행 - 효과적으로 제거 :
여기 및 둘째, 출력 레코드 구분자를 설정 ( $\
) 뭐든 8 진수 16 진수 값 이것은 (주어진 012
것이다 \n
). 경우에 $\
정의되고 그 각각의 단부에 추가 될 print
이 각각 첨부 개행 결과 있도록 통화 print
.
-pe
의지 p는 에 의해 지정된 스크립트를 적용한 후에 각각의 입력 라인 RINT -e
. 위에서 설명한 것처럼 모든 작업이 옵션 플래그로 수행되므로 스크립트가 없습니다!
perl -0x3a -l012 -pe '' <<<$PATH
. 설명 : -0
입력 레코드 구분 기호를 설정합니다 (16 진수 / 8 진수 표기법으로 지정, x3A는 콜론 임), -l
1) 입력 레코드 구분자를 cho니다 .2) 하나를 지정하면 출력 레코드 구분자를 설정합니다 (8 진수 표기법) , 012는 줄 바꿈입니다). -p
각 될 것입니다 $ _의 값, 밖으로 루프 인쇄 라인 에 읽어 보시기 바랍니다.
-F
정보 주셔서 감사합니다 . 나는 수년 동안 -F
함께 사용 해 왔으며 -an
, 다른 하나를 암시 한 것을 결코 깨닫지 못했습니다. 그건 그렇고, Serg가 Code Golf를 언급 한 것을 보았지만 이런 종류의 일에 유닉스와 리눅스를 즐기게 될 것이라고 생각합니다 .
-l
각 인쇄 호출의 끝에 주어진 출력 레코드 구분 기호도 추가합니다. 실제로, $/
출력 레코드 구분 기호가 정의 된 경우 print는 항상 문자열 끝에 출력 레코드 구분 기호를 추가합니다 . 기본적으로 undef입니다. 그래서 -l
jus sets $/
, 그러면 print는 줄 끝에 줄 바꿈을 추가합니다.
모든 스크립팅 언어가 이미 사용되었으므로 C를 사용하겠습니다. get_env()
함수를 사용하여 환경 변수를 얻는 것은 매우 쉽습니다 ( GNU C 라이브러리 설명서 참조 ). 나머지는 단순히 캐릭터 조작입니다
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
또한 "why not"때문에 명령 행 인수를 통한 대체 파이썬 버전이 있습니다. sys.argv
python -c 'import sys; print "\n".join(sys.argv[1].split(":"))' "$PATH"
루비는 C 컴파일러와 파이썬 인터프리터와 달리 기본적으로 우분투와 함께 제공되지 않지만 루비의 해결책은 다음과 같습니다.
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에 의해 사용되는 기본 구분 기호입니다 ($; 기본값은 nil이며 공백으로 분할 됨). -a
$ _. split을 호출합니다. 여기서 $ _는 gets ())를 사용하여 읽은 행이며 결과 배열을에 할당합니다 $F
.
-F
깃발 이 있다는 것을 몰랐습니다. 저는 루비로 시작해서 약간 조잡한 일을하고 있습니다.
ruby -0072 -ne 'puts chomp' <<<$PATH
. 설명 : -0
입력 레코드 구분 기호를 설정합니다 (8 진수 형식으로 문자를 지정하십시오. 072는 콜론 임). 루비는 Perl과 비슷한 방식으로 $ _를 사용합니다. ( -n
루프 에서 사용되는) gets () 메소드 는 $ _를 읽은 현재 줄로 설정합니다 chomp()
. 나는 여전히 당신을 더 좋아합니다. :)
-F
플래그가 더 짧습니다. 그렇게 echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c
하면 271 바이트이지만 8 진수 숫자는 276입니다. 물론 전체 명령에 대한 것입니다. 물론 코드 자체만으로도 puts $F
짧아집니다. 그건 그렇고, 당신은 코드 골프 에 대해 알고 있습니까? 가장 짧은 바이트 수로 퍼즐을 프로그래밍하는 솔루션을 제공하는 사이트입니다. 이것과 관련된 질문이 있습니다 : codegolf.stackexchange.com/q/96334/55572
더 많은 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"
Stephen Collyer의 "Bash Path Functions"를 사용합니다 ( 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 인용 -$ 'some \ ntext'설명
Shell Parameter Expansion- $ {parameter / pattern / string}에 대해 설명합니다. 패턴이 '/'로 시작하면 패턴의 모든 일치 항목이 문자열로 바뀝니다.
그래서 우리는 :
또 다른 AWK 방법은 각 디렉토리를 별도의 필드가 아닌 별도의 레코드 로 취급 하는 것 입니다 .
awk 'BEGIN{RS=":"} {print $0}' <<<"$PATH"
그 구문이 특히 직관적이라는 것을 알았습니다. 그러나 원하는 경우 print $0
암시 적 으로 만들어서 단축시킬 수 있습니다 (기본 조치이며 1
true로 평가되어 모든 행에 대해 수행됨).
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
아마 우분투 시스템에 공백이없는 있지만, 만일 그렇다면,이 여전히 작동합니다.
이 분야의 컬렉션으로 기록을 해석하는 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 가 레코드를 다시 작성 하도록하는 목적을 수행합니다 .
(이것은 단순히 테이블을 인쇄하는 것으로 표시된 정확한 예보다 구성 요소에서 추가 처리를 수행하는 경우에 더 유용합니다.)
$ PATH에 경로를 개별적으로 표시하는 방법
이것들은 각각의 사용 사례와 호환성 및 리소스 사용에 대한 우려를 바탕으로 선호되는 방법입니다.
tr
먼저 빠르고 기억하기 쉽고 읽기 쉬운 솔루션이 필요한 경우 에코 PATH
하고 파이프하여 변환 ( tr
) 하여 콜론을 개행 문자로 바꿉니다.
echo $PATH | tr : "\n"
파이프 때문에 두 가지 프로세스를 사용하는 단점이 있지만 터미널에서 해킹하는 경우 실제로 관심이 있습니까?
.bashrc
대화식 사용을 위해 상당히 영구적 인 솔루션을 원한다면 다음 명령의 별칭을 지정할 수 path
있지만이 솔루션의 가독성은 의문의 여지가 있습니다.
alias path="echo \"${PATH//:/$'\n'}\""
패턴이 '/'로 시작하면 패턴의 모든 일치 항목이 문자열로 바뀝니다. 일반적으로 첫 번째 일치 항목 만 교체됩니다.
위 명령은 Bash의 Shell Parameter Expansion을 사용하여 콜론을 줄 바꿈으로 대체합니다 .
${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
는 (AS, 특히 대쉬하는 우분투 일반적 별명 가장 POSIX 같은 포탄에서 작동해야하므로 POSIX에 의해 제공된다 sh
).
이것을 위해 파이썬을 사용해야합니까? 당신은 할 수 있습니다. 이것은 내가 생각할 수있는 가장 짧은 Python 명령입니다.
python -c "print('\n'.join('${PATH}'.split(':')))"
또는 Python 3 전용 (더 읽기 쉬운가?) :
python3 -c "print(*'${PATH}'.split(':'), sep='\n')"
이것들은 파이썬이있는 한 일반적인 쉘 환경에서도 작동해야합니다.
이 솔루션은 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