さまざまなパスを$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、ところで)。ありがとう。
.bash_profile
、このようにそれを追加しますalias path='tr ":" "\n" <<< "$PATH"'
bashのパラメーター展開を使用します。
echo "${PATH//:/$'\n'}"
これにより、すべて:
が$PATH
改行(\n
)に置き換えられ、結果が出力されます。の内容は$PATH
変更されません。
最初ののみを置き換える場合は:
、2番目のスラッシュを削除します。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:
は同じことを行いますが、もう1つシェルを使用します。最初のものは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
。$"
その値が印刷されたリストの各要素との間に印刷される特殊な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
により、Perl Compatible Regular Expressions(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(および他のシェル)のstring(<<<
)演算子を使用して、文字列をプログラムへの入力として渡します。はとcommand <<<"foo"
同等echo -n "foo" | command
です。私はいつも引用"$PATH"
符なしで引用していることに注意してください、シェルは改行文字を食べていたでしょう。
@ 7studはコメントに別のアプローチを示しましたが、これは含めるにはあまりにも良いことです。
$ perl -0x3a -l012 -pe '' <<<"$PATH"
それがゴルフとして知られているものです。-0
進又は16進数で入力レコードセパレータを指定します。これが「行」を定義するものであり、そのデフォルト値は\n
改行文字です。ここ:
ではx3a
、16進数のaに設定しています(try printf '\x3a\n'
)。-l
3つのことを行います。まず$/
、各行の末尾から入力レコード区切り文字()を削除し(実質的に:
ここを削除します$\
)、次に、出力レコード区切り文字()を指定された8進値または16進値(012
is \n
)に設定します。$\
が定義されている場合、各print
呼び出しの最後に追加されるため、各に改行が追加されますprint
。
-pe
意志pはによって与えられたスクリプトを適用した後、各入力ラインをRINT -e
。上記のオプションフラグによってすべての作業が行われるため、ここにはスクリプトはありません!
perl -0x3a -l012 -pe '' <<<$PATH
。説明:-0
入力レコード区切り文字を設定します(16進/ 8進表記で指定、x3Aはコロンです)、-l
2つのことを行います:1)入力レコード区切り文字を削除し、2)出力レコード区切り文字が指定されている場合は設定します(8進表記) 、012は改行です)。-p
各なります$ _の値は、外ループプリントラインは読ま。
-F
情報をありがとう。私は長年にわたって-F
と組み合わせて使用してきましたが-an
、他のものが暗示されていることに気付きませんでした。ちなみに、SergがCode Golfについて言及しているのを見ましたが、この種のことに興味があるなら、UnixとLinuxも楽しむと思います。
-l
各印刷呼び出しの最後に指定された出力レコード区切り文字も追加します。 実際、printは、出力レコード区切り$/
文字が定義されている場合、常に出力レコード区切り文字を文字列の末尾に追加します。デフォルトではundefです。したがって、-l
jusはを設定し$/
、それにより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
しかし、「なぜ」ではないため、コマンドライン引数を介した代替のPythonバージョンもあります sys.argv
python -c 'import sys; print "\n".join(sys.argv[1].split(":"))' "$PATH"
CコンパイラやPythonインタプリタとは異なり、RubyにはデフォルトではUbuntuが付属していませんが、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
セット$;
($;ゼロのデフォルト値は、空白で分割を持っている)文字列で使用されるデフォルトの区切り::分割で指定した文字に。 -a
$ _。splitを呼び出します。$ _はgets()を使用して読み込まれた行で、結果の配列をに割り当て$F
ます。
-F
フラグがあることを知りませんでした-私はRubyで始めたばかりなので、少し粗雑な方法でやっています。
ruby -0072 -ne 'puts chomp' <<<$PATH
。説明:-0
入力レコード分離文字を設定します(8進形式の文字を指定します。072はコロンです)。Rubyは、Perlと同様の方法で$ _を使用します。gets()メソッド(-n
ループで使用)は、読み込まれた現在の行に $ _を設定します。chomp()
引数なしでは、$ _を削除します。私はまだあなたのものが好きです。:)
-F
フラグ付きのものが短くなっています。そうした場合、echo "ruby -F: -ane 'puts $F' <<<$PATH" |wc -c
それはそれは271です私に語った、バイト、しかし進数の1が、コマンド全体のためだ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}'
Python経由。
$ echo $PATH | python3 -c 'import fileinput
for line in fileinput.input():
for i in line.split(":"):
print(i)'
Pythonではインデントが非常に重要であることに注意してください。
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'の説明
シェルパラメーターの展開 -$ {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
おそらく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
assignment 盛な割り当ては、AWK にレコードの再構築を強制する目的に役立ちます。
(これはおそらく、表を単に印刷するという正確な例よりも、コンポーネントで追加の処理を行う場合に役立つでしょう。)
jq -Rr 'gsub(":";"\n")' <<<$PATH
$ PATHのパスを個別に表示する方法
これらは、それぞれのユースケースと互換性とリソース使用量に関する懸念に基づいて、これを行うための好ましい方法です。
tr
まず、覚えやすくて読みやすい迅速な解決策が必要な場合は、それをエコーPATH
してパイプして翻訳(tr
)し、コロンを改行に変換します。
echo $PATH | tr : "\n"
パイプが原因で2つのプロセスを使用するというデメリットがありますが、単に端末をハッキングしているだけであれば、それを本当に気にしますか?
.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によって提供されている、それは(Ubuntuは通常、別名、特にダッシュ、貝殻ほとんどのようなPOSIXで動作するはずですので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