(これは複雑な環境で最も簡単な作業例です。)
d
ファイルを含むディレクトリがあります1.txt 2.txt 3.txt 4.wav
。私の現在のディレクトリは別の場所にあります。
ls d
報告し1.txt 2.txt 3.txt 4.wav
てください。
しかし、それが私が望むすべてだ1.txt 2.txt 3.txt
からですls d/*.txt
。
ただし、これはシェルがファイルを表示する前に拡張するため、d/
すべてのファイル名の前に次のものが追加されます。d/1.txt d/2.txt d/3.txt
*
ls
私が望むものを得るために、代わりに新しいシェルを作成すること1.txt 2.txt 3.txt
もできます。出力をフィルタリングするためのより良い方法、より薄く、落とし穴やエッジケースにあまり脆弱な方法はありますか?ls d | grep txt
ls d/*.txt | xargs basename -a
(cd d; ls *.txt)
ls
答え1
そしてzsh
:
printf '%s\n' d/*.txt(:t)
:t
csh履歴修飾子に似ていますが、glob修飾子では次のようになります。尾ファイル名。
返品:
files=(d/*.txt)
printf '%s\n' $files:t
Bourneに似た他のシェルでは、いつでも次のことができます。
(cd d && printf '%s\n' *.txt)
新しいシェルをフォークするのではなく、サブシェル環境を作成することに注意してください。ほとんどのシェル実装では、サブシェル環境はサブプロセスをフォークすることによって達成されますが、新しいシェルはその中で実行されません(新しいシェルではありませんが、新しいプロセスで同じシェルがフォークされます)。また、サブシェルの最後のコマンドが外部コマンドである場合、ほとんどのシェル(ではありませんbash
)は追加のプロセスを作成しないため、実行中のプロセスの総数はサブシェル環境がない場合と同じです。
ksh93
サブシェルをフォークしません。サブシェルを終了するときは、サブシェルで行われた変更を元に戻すことでこれを行います。したがって、(printf
組み込みの場合)追加の(cd d && printf '%s\n' *.txt)
プロセスは分岐しません。
また、ls
ファイルとコンテンツ引数として渡されるディレクトリです。ここでls
シェルから提供された名前だけを印刷する場合は必要ありませんが、こだわりの場合はそのls
オプション-d
を渡してディレクトリの内容を一覧表示しないようにする必要があります。
(cd d && ls -d -- *.txt)
答え2
あなたが要求したことを行う最も簡単な方法は次のとおりです。
$ ( cd d; ls *.txt )
1.txt 2.txt 3.txt
これはサブシェル内で発生するため、( ... )
ディレクトリの変更は永続的ではなく、これら2つのコマンドを実行した場合にのみ有効です。
より強力なバージョンは次のとおりです。
$ ( cd d && ls -d -- *.txt )
1.txt 2.txt 3.txt
ls
ディレクトリの変更が成功しないと、その内容は実行されず、ディレクトリのls
内容の代わりにリストされ、名前がダッシュで始まるファイルはオプションとして提供されません。
位置パラメータ(など)$1
を変更してもよい場合は、この方法も比較的簡単です。$2
$ set d/*.txt
$ for f do printf '%s\n' "${f#d/}"; done
1.txt
2.txt
3.txt
これはPOSIXシェルで動作します。
$ dash -c 'set d/*.txt; for f do printf "%s\n" "${f#d/}"; done'
1.txt
2.txt
3.txt
GNU findを使用できます-printf
。
$ find d -maxdepth 1 -iname "*.txt" -printf "%f\n" | sort
1.txt
2.txt
3.txt
しかし、これは十分に複雑になりました。申し訳ありません。私が知っている限り、もう「簡単な」解決策はありません。