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

expr bash for sed a line in log does not work

我的目标是sed第100行,转成字符串,然后把句子的数据分离成word

#!/bin/bash
fid=log.txt;

sentence=`expr sed -n '100p' ${fid}`;
for word in $sentence
do
    echo $word
done

但显然这失败了。

expr: syntax error

有人可以告诉我我做错了什么吗?以前对于它有效的数字。

#!/bin/bash

fid=log.txt;

sentence=$(sed -n '100p' ${fid});
for word in $sentence
do
    echo $word
done

输入美元符号和括号解决问题

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

expr 1 + 1

只有这个可以:

sentence=`sed -n '100p' ${fid}`;

expr 在这里似乎没有用处,如果有用,在大多数情况下,sed 命令传递给它肯定不是有效或有用的东西.你可能应该把它拿出来。

但是,下面的循环也是有问题的。 Unquoted variables in shell script are very frequently an error。在这种情况下,您不能引用传递给 for 循环的内容(这将导致循环仅 运行 一次,循环变量设置为引用的字符串)但您也不能防止 shell 对未加引号的字符串执行通配符扩展。因此,如果字符串恰好包含 *,shell 会将其扩展为当前目录中的文件列表,例如

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

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

即如果行号不是100,则删除这一行,从下一行重新开始。否则,我们在第 100 行;将 运行 的白色 space 替换为换行符,(打印)并退出。

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

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

方括号内的东西是一个space和一个文字制表符;在 Bash 中,使用默认键绑定,键入 ctrl-V,tab 以生成文字选项卡。)

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