grep + grep + sed = sed: no input files

11

有人能帮我吗?

grep " 287 " file.txt | grep "HI" | sed -i 's/HIS/HID/g' 

sed: no input files

我也尝试了 xargs

grep " 287 " file.txt | grep HI | xargs sed -i 's/HIS/HID/g'
sed: invalid option -- '6'

这个效果很好

grep " 287 " file.txt | grep HI

7
-i 是指“原地编辑”,你无法 “原地编辑” 一个流,因此 sed 需要一个文件作为输入,但你没有提供任何文件。 - Etan Reisner
是的,但如果我去掉-i,它就不会写入文件了... - nicetry
这两个命令都没有写入文件。如果你想要从 sed 中输出到文件,你需要将其重定向到一个文件中。-i 不能帮助你。你也不能只是在末尾加上 > file.txt,因为那会先截断文件。话虽如此,sed 可以为你完成所有的过滤操作,所以你根本不需要 grep - Etan Reisner
1
grep " 287 " file.txt | grep "HI" | sed 's/HIS/HID/g'这个命令只会打印输出结果,无法保存。 - nicetry
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Etan Reisner
newfile.txt 这只会输出 grep 的行,而不是整个文件...
- nicetry
1个回答

10
如果您想保留您的流水线:
f=file.txt
tmp=$(mktemp)
grep " 287 " "$f" | grep "HI" | sed 's/HIS/HID/g' > "$tmp" && mv "$tmp" "$f"

或者,简化:

sed -i -n '/ 287 / {/HI/ s/HIS/HID/p}' file.txt

这将过滤掉不包含“287”和“HI”的任何行 - 这是您想要的吗?我怀疑您真正想要的是这个:

sed -i '/ 287 / {/HI/ s/HIS/HID/}' file.txt

对于与/ 287 /匹配的行,执行大括号中的命令。在其中,对于与/HI/匹配的行,搜索第一个“HIS”,并替换为“HID”。如果未指定-n,则sed隐式打印所有行。

其他执行相同操作的命令:

awk '/ 287 / && /HI/ {sub(/HIS/, "HID")} {print}' file.txt > new.txt
perl -i -pe '/ 287 / and /HI/ and s/HIS/HID/' file.txt

除了最近版本的gawk有gawk -i inplace选项外,awk没有“原地”处理选项。


1
是的,最后一个完美地运作了,你能解释一下吗? - nicetry
当运行sh时,我该如何更改file.txt为$1。其中$1是用户输入的。 - nicetry
你认为你会怎么做呢? - glenn jackman
建议您提出一个新问题。 - glenn jackman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接