sed的expr bash日志中的一行不起作用



我的目标是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在这里似乎没有起到有用的作用,如果起到了作用,那么在大多数情况下,传递给它的sed命令肯定不是一个有效或有用的东西。你可能应该把它拿出来。

但是,下面的循环也是有问题的。shell脚本中未引用的变量经常是一个错误。在这种情况下,您不能引用传递给for循环的内容(这将导致循环只运行一次,循环变量设置为带引号的字符串),但也不能阻止shell对未带引号的串执行通配符扩展。因此,例如,如果字符串恰好包含*,shell会将其扩展到当前目录中的文件列表。

幸运的是,这一切都可以在一个稍微复杂一点的sed脚本中完成。

sed '100!d;s/[ t]+/n/g;q' "$fid"

也就是说,如果行号不是100,则删除这一行并从下一行开始。否则,我们将处于第100行;用换行符替换空白,(print)并退出。

(反斜杠转义码tn并不是通用的可移植代码;用于重复的+也是一个可选的扩展。我相信也有sed变体不喜欢分号作为命令分隔符。请参阅sed手册页,进行实验,如果其他一切都失败了,可以切换到Awk或Perl。以防万一,这里有一个甚至适用于Mac OSX的版本:

sed '100!d
     s/[    ][  ]*/
/g;q' log.txt

方括号内的内容是一个空格和一个文字标签;在Bash中,使用默认的键绑定,键入ctrl-V,tab以生成一个文本选项卡。)

顺便说一句,这也消除了变量捕获反模式。捕获变量的输出是有充分理由的,但如果可以避免,您通常会得到一个更简单、更健壮、更高效的脚本,以及更惯用、更优雅的脚本。(在这种孤立的情况下,我也没有理由将日志文件名放在变量中;但在更大的脚本中,这可能是有意义的。)

我认为在这种情况下不需要expr命令。expr用于进行计算。类似于:

expr 1 + 1

只有这一个很好:

sentence=`sed -n '100p' ${fid}`;
#!/bin/bash
fid=log.txt;
sentence=$(sed -n '100p' ${fid});
for word in $sentence
do
    echo $word
done

放一个美元符号和括号来解决问题

最新更新