我的目标是 sed 第 100 行并将其转换为字符串,然后将句子的数据分离为单词
#!/bin/bash
fid=log.txt;
sentence=`expr sed -n '100p' ${fid}`;
for word in $sentence
do
echo $word
done
但显然这已经失败了。
expr: syntax error
有人可以让我知道我做错了什么吗?以前它工作的数字。
在这种情况下,我认为您不需要 expr 命令。expr 用于进行计算。就像是:
expr 1 + 1
只是这个很好:
sentence=`sed -n '100p' ${fid}`;
在这里expr
似乎没有用处,如果有sed
,在大多数情况下,传递给它的命令肯定不是有效或有用的东西。你可能应该把它拿出来。
但是,下面的循环也有问题。shell 脚本中未加引号的变量经常是一个错误。在这种情况下,您不能引用传递给for
循环的内容(这将导致循环只运行一次,并且循环变量设置为带引号的字符串),但您也不能阻止 shell 执行通配符扩展不带引号的字符串。因此,如果字符串恰好包含*
,例如,shell 会将其扩展为当前目录中的文件列表。
幸运的是,这一切都可以在稍微复杂一点的sed
脚本中完成。
sed '100!d;s/[ \t]\+/\n/g;q' "$fid"
也就是说,如果行号不是 100,则删除此行并从下一行重新开始。否则,我们在第 100 行;用换行符替换空格的运行,(打印)并退出。
(反斜杠转义码并不是通用的可移植的;\t
对于重复也是一个可选的扩展。我相信也有不喜欢分号作为命令分隔符的变体。请参阅您的手册页,进行实验,如果其他一切都失败了,也许切换到Awk 或 Perl。为了以防万一,这里有一个甚至可以在 Mac OSX 上运行的版本:\n
\+
sed
sed
sed '100!d
s/[ ][ ]*/\
/g;q' log.txt
方括号内的内容是空格和文字制表符;在 Bash 中,使用默认键绑定,键入 ctrl-V, tab 以生成文字选项卡。)
顺便说一句,这也摆脱了变量捕获反模式。将输出捕获到变量是有充分理由的,但如果可以避免,您通常会得到一个更简单、更健壮、更高效、更惯用和优雅的脚本。(在这种孤立的情况下,我也认为没有理由将日志文件名放在变量中;但在更大的脚本中,这可能是有意义的。)
#!/bin/bash
fid=log.txt;
sentence=$(sed -n '100p' ${fid});
for word in $sentence
do
echo $word
done
放一个美元符号和括号解决问题