bash执行tr命令报extra operand错误,脚本中报错但命令行重定向正常
报错核心原因
这个报错的本质是你在脚本里漏写了tr的输入来源,错误把文件路径作为参数传给了tr:
- tr的设计逻辑是仅从标准输入读取待处理的字符流,本身不支持将文件路径作为命令行参数接收输入。这里有个很容易踩的设计差异:grep、sed、awk这类常用文本处理命令,都支持直接把文件路径作为参数读取内容,唯独tr做了特殊设计,不接收文件路径参数,只从标准输入拿数据。
- 你当前脚本中的
tr -d "\n" foocounthtml.txt > foocountnonewlines.txt命令,会向tr传递3个操作数:-d是删除模式选项,"\n"是需要删除的字符集,foocounthtml.txt是额外多出来的独立参数。而tr在删除模式下只允许接收1个待处理的字符集参数,多出来的路径参数就会触发你看到的“extra operand”报错。
为什么命令行交互时运行正常
你在交互终端敲命令时觉得同样的写法没问题,本质是你在交互场景下漏记了输入环节:
- 交互状态下你大概率是通过重定向或者管道给tr喂输入的,比如写成
tr -d "\n" < foocounthtml.txt或者cat foocounthtml.txt | tr -d "\n",这两种写法下tr完全是从标准输入取数据,根本不会碰到“把文件名当参数”的问题,自然能正常运行。 - 等你把命令迁移到脚本中固化时,手滑漏了输入重定向的
<或者管道环节,直接把文件名跟在tr的参数后面,就会触发脚本里的报错。
修正后的可用写法
完全对齐你现有脚本逻辑的修正版本:
#!/bin/bash wget -O foocounthtml.txt "http://foopage" # 给tr补上输入重定向,把文件内容作为标准输入喂给tr tr -d "\n" < foocounthtml.txt > foocountnonewlines.txt
针对你只需要提取页面中数字的需求,还可以简化流程,不需要生成两个中间临时文件:
#!/bin/bash # wget直接输出到标准输出,通过管道串接处理逻辑,直接拿到最终数值 wget -O - "http://foopage" | grep -oE '[0-9]+'
你提到的sed原地修改的方案也可以实现同等效果,比如
sed -i 's/[^0-9]//g' foocounthtml.txt直接把非数字内容替换掉,拿到目标数值。但本质上只要给tr补上正确的输入来源,tr的写法本身没有任何问题。
内容的提问来源于stack exchange,提问作者capser
相关产品推荐
相关产品推荐

