文字列の最初の単語を取得する方法は?


43

'echo *' 私が次の出力を取得したとき:

file1 file2 file3 ...

私が欲しいのは最初の言葉を選ぶことです。どうすれば続行できますか?


1
@mattdm lsファイル名の1つに空白が含まれている場合、使用は機能しません。
ヘルパーメソッド

2
どのように単語を定義しますか?最初のファイルがSunset on a beach.jpgであるSunset場合、ファイル名またはファイル名全体ですか?どうSea, sex and sun.oggSeaSea,またはファイル名全体ですか?
ステファンシャゼル

@mattdm ls | head -1a.patch p.py、最初の単語ではなく、アルファベット順のファイルでさえないランダムなものを私に与えます。
phuclv

回答:


52

あなたはそれをawkを通してパイプし、最初の単語をエコーさせることができます

echo * | head -n1 | awk '{print $1;}'

または、文字列を切り取って最初の単語を選択します。

echo *  | head -n1 | cut -d " " -f1

または、sedを使用してパイプ処理し、最初の単語以外のすべてを削除します

echo * | head -n1 | sed -e 's/\s.*$//'

| head -n1nitpickersを満たすために追加されました。文字列に改行| head -n1が含まれている場合、重要なコマンドが渡された文字列から最初の単語を選択する前に、最初の行が最初に選択されます。


1
は、最初の単語ではなく、すべての行の最初の単語を返します。
ステファンシャゼル

2
何行がecho *生成されるのだろうか?
バナンイン

それは、名前に改行文字を含むファイルの数、環境、bashのコンパイル方法、または呼び出されるファイル-eまたは-ee...がリストに表示されるかどうか\n、ファイル名に表示される時間に依存します。ファイルがあれば-n、それも...すべてで任意の行を返さない可能性があります
ステファンChazelas

さて、私たちはまだbashについて話しているのです。1。通常、bashは改行を含む文字列を改行を含む1つの文字列として渡しません。ファイル名は\ nとして表示されます。4.-5.で始まるファイル名の場合は3が保持されます。私は複数行の問題の少なくとも世話に私のアドバイスを編集し、そのことについては、少なくとも1つの文字列、6
Bananguin

1
5つのポイントはすべて偽です。空のディレクトリで試してください:touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'(Unixに準拠する必要があるxpg_echo場合bashはいつでも有効です)。そして、別の空のディレクトリ:touch ./-n; bash -c 'echo * | wc -l'。行は、改行文字で終了する一連の文字です。場合はecho出力しない改行文字を行い、それが出力しない任意の行を行います。テキストユーティリティの挙動が好きcutawkまたはsed最後の改行文字や行動が実装で変動した後の入力が余分な文字を持っている場合は指定されません。
ステファンシャゼル

18

posixyシェルを想定(/bin/shまたは/bin/bashこれを行うことができます)

all=$(echo *)
first=${all%% *}

コンストラクト${all%% *}は、部分文字列の削除の例です。これ%%*、変数の右端から最長一致(スペースの後に何かが続く)を削除することを意味しますall。文字列操作の詳細については、こちらをご覧ください

このソリューションでは、区切り文字がスペースであると想定しています。ファイル名を使用してこれを実行している場合、スペースを使用すると壊れます。


良いですね。しかし、私はシンプルが好きで、と複数の非ハック他のバージョンheadcut
アンワル

4
IMO、head、cut&sedはそれほど単純ではありません。組み込みのパラメーター置換が効率的にジョブを実行するときに別のツールを生成する理由。この答えは、スペースで区切られた単語のリストの最初の単語(OPが要求するすべての単語)を選択する最も効率的で移植性の高い方法です。
フアン

7

最初の単語ではなく最初のファイル名が本当に必要だと仮定すると、空白で中断しない方法があります:

shopt -s nullglob
files=(*)
printf '%s\n' "${files[0]}"

1
最初の言葉は、あまりにも、簡単だろう:files=($(echo *))
Hauke Laging

2
ただし、「-n」、「-e」、「-ne」、「-Enenene」で中断しますbashが、コンパイル方法や環境によっては、おそらくバックスラッシュ文字で中断します。
ステファンシャゼル

2
@HaukeLaging、グロビングを無効にする必要があります。のようにtext=$(echo *); set -f; files=($text)、それ以外の場合はより多くのワイルドカードを展開できます。
ステファンシャゼル

3
およびfiles=$(echo *); echo ${files%% *}
vdegenne

1
@memnoch_proxy空白を含むファイル名で中断します。注意して使用してください。
クリスダウン

5

位置パラメータを使用できます

set -- *
echo "$1"

3
補助スコープで実行しない限り、これによりスクリプトの他の引数がすべて破棄されることに注意してください。また*、ディレクトリにファイルがない場合にも展開されます。
クリスダウン

shopt -s nullglobそれを処理します
グレンジャックマン



1

最初のファイル名全体を取得する:

shopt -s nullglob
printf '%s\000' * | grep -z -m 1 '^..*$'
printf '%s\000' * | ( IFS="" read -r -d "" var; printf '%s\n' "$var" )
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.