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