如何用php从文件中删除一行?
我有一个名为 $dir
的文件和一个名为 $line
的字符串,我知道这个字符串是该文件的完整行,但我不知道它的行号,我想将其从文件中删除,我该怎么办?
可以用awk吗?
I have a file named $dir
and a string named $line
, I know that this string is a complete line of that file but I don't know its line number and I want to remove it from file, what should I do?
Is it possible to use awk?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
逐行读取,并将除匹配行之外的所有行写入另一个文件。然后替换原来的文件。
Read the lines one by one, and write all but the matching line to another file. Then replace the original file.
这只会查看每一行,如果不是您想要删除的内容,它将被推送到一个数组,该数组将被写回文件。
this will just look over every line and if it not what you want to delete, it gets pushed to an array that will get written back to the file. see this
不使用awk也可以解决:
It can be solved without the use of awk:
另一种方法是逐行读取文件,直到找到匹配项,然后将文件截断到该点,然后附加其余行。
Another approach is to read the file line by line until you find a match, then truncate the file to that point, and then append the rest of the lines.
这里的所有答案都有一个共同点,即它们将完整的文件加载到内存中。下面是删除一行(或多行)而不将文件内容复制到变量的实现。
这个想法是迭代文件行。如果应删除一行,则行长度将添加到
$byte_offset
中。然后下一行“向上”移动$byte_offset
字节。这是通过以下所有行完成的。如果处理了所有行,则文件最后$byte_offset
字节将被删除。我想这对于较大的文件来说会更快,因为没有复制任何内容。我猜想在某些文件大小下,其他答案根本不起作用,而这个答案应该起作用。但我没有测试过。
用法:
fremove_line()
函数的代码:All answeres here have in common, that they load the complete file into the memory. Here is an implementation of removing one (or more) line(s) without coyping the files content into a variable.
The idea is to iterate over the files lines. If a line should be removed, the lines length is added to the
$byte_offset
. The next line is then moved$byte_offset
bytes "upwards". This is done with all following lines. If all lines are processed, the files last$byte_offset
bytes are removed.I guess that this is faster for bigger files because nothing is copied. And I guess that at some file size the other answers do not work at all while this one should. But I didn't test it.
Usage:
The code of the
fremove_line()
function:如果您要在一行中查找子字符串 (ID) 并希望用新行替换旧行,这也很有用。
代码:
示例:
输入:“123,student”
旧文件:
运行代码将文件更改为:
新文件:
This is also good if you're looking for a substring (ID) in a line and want to replace the old line with the a new line.
Code:
Example:
input: "123,student"
Old file:
Running the code will change file to:
New file:
将文本转换为数组,删除第一行并重新转换为文本
Convert text to array, remove first line and reconvert to text
我认为处理文件的最佳方法是将它们视为字符串:
以下是正在执行的操作的简要说明:获取整个文件内容,将内容拆分为行(即作为数组),找到匹配项( es)并删除它们,将所有行连接在一起,并将结果保存回文件(仅当发生任何更改时)。
现在让我们使用它:
注意:
您可以使用
fopen()
系列函数代替SplFileObject
,但我建议使用对象形式,因为它是基于异常的,更健壮且更高效(至少在本例中是这样)。使用 foreach 迭代时
unset()
数组的元素是安全的(有一条注释 here 显示它可能会导致意外结果,但这是完全错误的:正如您在示例代码中看到的,$value
被复制(即它不是引用),删除数组元素不会影响它)。$line
不应包含像\n
这样的换行符,否则,您可能会执行大量冗余搜索。不要使用
而不是
原因是,第一种情况不会删除该行,它只是清除该行(并且会保留不需要的空行)。
希望有帮助。
I think the best way to work with files is to act them like strings:
Here is a brief description of what is being done: Get the whole file content, split the content into its lines (i.e. as an array), find the match(es) and remove them, join all lines together, and save the result back to the file (only if any changes happened).
Let's now use it:
Notes:
You can use
fopen()
family functions instead ofSplFileObject
, but I do recommend the object form, as it's exception-based, more robust and more efficient (in this case at least).It's safe to
unset()
an element of an array being iterated using foreach (There's a comment here showing it can lead unexpected results, but it's totally wrong: As you can see in the example code,$value
is copied (i.e. it's not a reference), and removing an array element does not affect it).$line
should not have new line characters like\n
, otherwise, you may perform lots of redundant searches.Don't use
instead of
The reason is, the first case doesn't remove the line, it just clears the line (and an unwanted empty line will remain).
Hope it helps.
像这样:
Like this: