如何获得字符串的第一个单词?


43

当我'echo *' 得到以下输出时:

file1 file2 file3 ...

我想要的是挑选第一个单词。我该如何进行?


1
@mattdm ls如果文件名之一包含空格,则使用将不起作用。
helpermethod

2
您如何定义单词?如果第一个文件是Sunset on a beach.jpg,应该是Sunset还是整个文件名?那Sea, sex and sun.oggSeaSea,或整个文件名?
斯特凡Chazelas

@mattdm ls | head -1给了我一些随机的东西,比如a.patch p.py不是第一个单词,甚至不是字母顺序的文件。
phuclv

Answers:


52

您可以将其通过awk传递,并使其回显第一个单词

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

或者您将字符串切开并选择第一个单词:

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

或者您将其通过thoged管道传输,并删除第一个单词以外的所有内容

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

添加了| head -n1以满足nitpickers。如果您的字符串包含换行符,| head -n1则在重要命令从传递给它的字符串中选择第一个单词之前,将首先选择第一行。


1
会返回每行的第一个单词,而不是第一个单词。
斯特凡Chazelas

2
我想知道会echo *产生多少行
Bananguin

这取决于有多少文件的名称中包含换行符,或者取决于环境,bash的编译方式,或者列表中是否出现了名为-e-ee... \n的文件,文件名中显示了多少时间。如果有一个名为-n,它甚至可能不会返回所有任意行...
斯特凡Chazelas

好吧,我们仍然在谈论bash和1.通常bash不会将带有换行符的字符串作为带有新行的字符串传递。2.在文件名中包含换行符是非常困难和不寻常的(不可能吗?)3. a中的\ n文件名将显示为\ n4。3对于以-5开头的文件名成立,即使用-n或-e调用,echo也会打开stdout并在完成后将其关闭,当然,它将返回一行,并且在至少一个字符串,就这个问题6。我编辑了我的建议,以便至少处理多行问题
Bananguin

1
所有5分均为假。尝试在一个空的目录:touch '$a\nb' 'a\nb'; env BASHOPTS=xpg_echo bash -c 'echo * | wc -l'xpg_echo无论启用bash要求是Unix的认可标准)。并在另一个空目录中:touch ./-n; bash -c 'echo * | wc -l'。行是由换行符终止的字符序列。如果echo不输出换行符,则不输出任何行。文本实用程序的行为,例如或,如果输入在最后一个换行符之后有多余的字符,并且行为在各个实现中有所不同cut,则未指定。awksed
斯特凡Chazelas

18

假设使用posixy shell(/bin/sh/bin/bash可以执行此操作)

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

该构造${all%% *}删除子字符串的一个示例。该%%方法*从变量的右端删除最长的匹配项(空格后跟任何空格)all。您可以在此处阅读有关字符串操作的更多信息。

此解决方案假定分隔符是一个空格。如果使用文件名执行此操作,那么任何带空格的文件都会将其破坏。


好东西。但是,我喜欢与headcut
Anwar

4
国际海事组织,头,切&sed不太简单。当内置参数替换有效地完成工作时,为什么还要生成另一个工具。这个答案是最有效,最便捷的方式,可以从空格分隔的单词列表中选出第一个单词(这是OP所要求的)。
胡安

7

假设您确实想要第一个文件名而不是第一个单词,这是一种在空格上不会中断的方法:

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

1
第一个单词也很容易:files=($(echo *))
Hauke Laging,

2
它会在“ -n”,“-e”,“-ne”,“-Enenene” ...上中断,并取决于如何bash编译或环境,可能还会使用反斜杠字符。
斯特凡Chazelas

2
@HaukeLaging,您需要禁用通配符。如:text=$(echo *); set -f; files=($text),否则可以扩展更多的通配符。
斯特凡Chazelas

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

1
@memnoch_proxy它将在包含空格的文件名上中断,请谨慎使用。
克里斯·

5

您可以使用位置参数

set -- *
echo "$1"

3
请注意,除非在辅助作用域中运行,否则这将破坏脚本的其他任何参数。*如果目录中没有文件,它将扩展为。
克里斯·

shopt -s nullglob会解决这个问题
glenn jackman

3

检查以下替代方法之一:

$ FILE=($(echo *))
$ FILE=$(echo * | grep -o "^\S*")
$ FILE=$(echo * | grep -o "[^ ]*")
$ FILE=$(find . -type f -print -quit)

然后,您可以通过打印它echo $FILE

另请参阅:grep输出中唯一的第一个单词?



1

获取整个第一个文件名:

shopt -s nullglob
printf '%s\000' * | grep -z -m 1 '^..*$'
printf '%s\000' * | ( IFS="" read -r -d "" var; printf '%s\n' "$var" )
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.