如何从文件中读取一系列行,然后删除每一行?
显然我可以这样读:
while read -r line; do
echo $line
done < myfile.txt
但如果我这样做:
while read -r line; do
echo $line
sed '1d' myfile.txt
done < myfile.txt
我只得到第一行
我正在寻找一种优雅的方式来读取一行,对其执行某些操作,然后在转到文件中的下一行之前将其删除。
答案1
我宁愿sed
只调用一次,然后在每一行迭代中调用。如果您想更改原始文件,您可以添加-我(- 到位) 选项sed
。
unset n
while read -r line; do
echo $line
: $((n++))
done < myfile.txt
sed "1,$n d" myfile.txt
答案2
你可以做:
sed -n '$d;w file2' >file1 <<IN
$(cat file1; echo .)
IN
这将安全地将 file1 中的每一行写入 file2,同时删除 file1 中的每一行。 shell 安全地处理中间临时文件 - 它创建一个临时文件,然后在向其写入单个字节之前将其从文件系统中删除。
一旦sed
释放文件描述符(在 EOF 或终止时 - 以先到者为准)该文件根本不存在。与常见sed -i
选项不同,这不依赖于sed
自身清理(如果处理意外中断,则可能不会发生)并且它也不带有该-i
选项所暗示的相同权限不一致。
并且应用程序不需要像演示的那样是全局的 - 这些行可以从原始文件中删除和/或有选择地写入单独的输出......
sed -n '$d;/pattern1/w file2
/pattern2/p' >file1 <<IN
$(cat file1; echo .)
IN
...演示如何仅将文件 1 中匹配的行/pattern2/
打印回文件 1,以及如何仅将文件 1 中匹配的行/pattern1/
写入w
文件 2。任何其他sed
命令当然也适用。
不过,可能值得注意的是,对于大多数 shell 来说,这不会从 file1 中继承 NUL 字节(这通常不是sed
工作中关心的问题)- 虽然这样的事情是可能的zsh
。
答案3
一旦文件被正确处理,您就可以用此代码片段替换文件的每一行(如果处理失败,请勿删除,因此您可以在需要时重新处理它们):
while read; do
if some_command_worked_correctly; then
sed -i '1,1 d' file-to-read
fi
done < file-to-read