通常、私が入力したディレクトリから最初のファイルの名前を表示したい場合:
ls raw/all | head -n 1
しかし、ディレクトリに多くのファイルがあると、長い時間がかかります
たとえば、900 k近くのファイルがあるdirの場合、次の測定値があります。
time ls raw/all | head -n 1
real 0m17.250s | 0m10.328s | 0m6.334s
user 0m3.224s | 0m3.884s | 0m3.192s
sys 0m0.544s | 0m0.664s | 0m0.572s
whileすべてのファイルをループするには:
time ls raw/all | wc -l
real 0m6.455s | 0m5.869s | 0m5.228s
user 0m3.612s | 0m3.468s | 0m4.072s
sys 0m0.460s | 0m0.784s | 0m0.624s
効率的方法で最初のファイルの名前をどのように印刷しますか?
これには注意が必要です。 2つのアプローチ:
アプローチ1; find
:
_find . -mindepth 1 -print -quit
_
find
および_-print
_ sは最初に見つかったファイルであり、_-quit
_ sはすぐに見つかりました。 _-mindepth 1
_は、現在のディレクトリの_.
_ハードリンクとの一致を防ぎます。
通常のファイルのみに関心がある場合は、_-type f
_を追加します。
_find . -type f -print -quit
_
_-mindepth 1
_は、ディレクトリである_.
_が一致しないため、削除できます。
アプローチ2; sh
、stdbuf
、およびawk
:
これは、多すぎるファイルに対して_ARG_MAX
_がトリガーされることに注意してください(引数リストが_ARG_MAX
_バイトを超えて長くなりすぎます)。その場合は、アプローチ1を使用します
printf
、echo
)*
_、展開を行う(照合順序は、指定されたls
の_LC_COLLATE
_のlocale
と同じでなければなりません)stdbuf -o0
_(stdbuf
には、GNU coreutils
が付属)を使用して、printf
/echo
のSTDOUTストリームをアンバッファーします|
_)最初のレコードを印刷した後、printf
/echo
のSTDOUTをawk
およびexit
にawk
が終了すると、stdbuf
(printf
)はSIGPIPE
を受け取り、強制終了されますprintf
を使用して、ASCII NUL(_\0
_)で区切られたファイル名を取得し、awk
のレコード区切り文字として_\0
_を使用して、ファイル名が関係しているこれらをまとめる:
_stdbuf -o0 printf '%s\0' * | awk 'BEGIN{RS="\0"} {print; exit}'
_