从文件中读取行然后删除

从文件中读取行然后删除

如何从文件中读取一系列行,然后删除每一行?

显然我可以这样读:

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

相关内容