Respostas:
Primeiro, abra o arquivo e obtenha todas as suas linhas. Em seguida, reabra o arquivo no modo de gravação e escreva suas linhas de volta, exceto a linha que você deseja excluir:
with open("yourfile.txt", "r") as f:
lines = f.readlines()
with open("yourfile.txt", "w") as f:
for line in lines:
if line.strip("\n") != "nickname_to_delete":
f.write(line)
Você precisa strip("\n")
do caractere de nova linha na comparação, porque se o arquivo não terminar com um caractere de nova linha, o último line
também não.
Solução para esse problema com apenas uma única abertura:
with open("target.txt", "r+") as f:
d = f.readlines()
f.seek(0)
for i in d:
if i != "line you want to remove...":
f.write(i)
f.truncate()
Esta solução abre o arquivo no modo r / w ("r +") e utiliza o recurso de redefinição do ponteiro f e truncar para remover tudo após a última gravação.
for
loop, você terminará com um arquivo parcialmente substituído, com linhas duplicadas ou uma linha cortada pela metade. Você pode querer f.truncate()
logo depois f.seek(0)
. Dessa forma, se você receber um erro, acabará com um arquivo incompleto. Mas a solução real (se você tiver espaço em disco) é gerar um arquivo temporário e usá-lo os.replace()
ou pathlib.Path(temp_filename).replace(original_filename)
trocá-lo pelo original depois que tudo tiver sido bem-sucedido.
i.strip('\n') != "line you want to remove..."
como mencionado na resposta aceita, que resolveria perfeitamente meu problema. Porque simplesmente i
não fez nada por mim
A melhor e mais rápida opção, em vez de armazenar tudo em uma lista e reabrir o arquivo para gravá-lo, é na minha opinião reescrever o arquivo em outro lugar.
with open("yourfile.txt", "r") as input:
with open("newfile.txt", "w") as output:
for line in input:
if line.strip("\n") != "nickname_to_delete":
output.write(line)
É isso aí! Em um loop e apenas um, você pode fazer a mesma coisa. Será muito mais rápido.
(output.write(line) for line in input if line!="nickname_to_delete"+"\n")
subprocess.call(['mv', 'newfile.txt', 'yourfile.txt'])
os.replace
(novo no python v 3.3) é mais multiplataforma do que uma chamada de sistema mv
.
Esta é uma "bifurcação" da resposta do @Lother (que eu acredito que deve ser considerada a resposta certa).
Para um arquivo como este:
$ cat file.txt
1: october rust
2: november rain
3: december snow
Este garfo da solução Lother funciona bem:
#!/usr/bin/python3.4
with open("file.txt","r+") as f:
new_f = f.readlines()
f.seek(0)
for line in new_f:
if "snow" not in line:
f.write(line)
f.truncate()
Melhorias:
with open
, que descartam o uso de f.close()
if/else
para avaliar se a string não está presente na linha atualO problema com a leitura de linhas na primeira passagem e a alteração (exclusão de linhas específicas) na segunda passagem é que, se o tamanho dos arquivos for grande, a memória ficará sem RAM. Em vez disso, uma abordagem melhor é ler as linhas, uma a uma, e gravá-las em um arquivo separado, eliminando as que você não precisa. Eu executei essa abordagem com arquivos de 12 a 50 GB e o uso da RAM permanece quase constante. Somente os ciclos da CPU mostram o processamento em andamento.
Gostei da abordagem fileinput, conforme explicado nesta resposta: Excluindo uma linha de um arquivo de texto (python)
Digamos, por exemplo, que eu tenho um arquivo com linhas vazias e quero remover linhas vazias, eis como eu o resolvi:
import fileinput
import sys
for line_number, line in enumerate(fileinput.input('file1.txt', inplace=1)):
if len(line) > 1:
sys.stdout.write(line)
Nota: As linhas vazias no meu caso tinham comprimento 1
Se você usa Linux, pode tentar a seguinte abordagem.
Suponha que você tenha um arquivo de texto chamado animal.txt
:
$ cat animal.txt
dog
pig
cat
monkey
elephant
Exclua a primeira linha:
>>> import subprocess
>>> subprocess.call(['sed','-i','/.*dog.*/d','animal.txt'])
então
$ cat animal.txt
pig
cat
monkey
elephant
Eu acho que se você ler o arquivo em uma lista, faça o que você pode percorrer na lista para procurar o apelido do qual deseja se livrar. Você pode fazer isso de maneira muito eficiente sem criar arquivos adicionais, mas precisará gravar o resultado novamente no arquivo de origem.
Aqui está como eu poderia fazer isso:
import, os, csv # and other imports you need
nicknames_to_delete = ['Nick', 'Stephen', 'Mark']
Estou assumindo que nicknames.csv
contém dados como:
Nick
Maria
James
Chris
Mario
Stephen
Isabella
Ahmed
Julia
Mark
...
Em seguida, carregue o arquivo na lista:
nicknames = None
with open("nicknames.csv") as sourceFile:
nicknames = sourceFile.read().splitlines()
Em seguida, itere na lista para corresponder às suas entradas a serem excluídas:
for nick in nicknames_to_delete:
try:
if nick in nicknames:
nicknames.pop(nicknames.index(nick))
else:
print(nick + " is not found in the file")
except ValueError:
pass
Por fim, escreva o resultado novamente no arquivo:
with open("nicknames.csv", "a") as nicknamesFile:
nicknamesFile.seek(0)
nicknamesFile.truncate()
nicknamesWriter = csv.writer(nicknamesFile)
for name in nicknames:
nicknamesWriter.writeRow([str(name)])
nicknamesFile.close()
Em geral, você não pode; você precisa escrever o arquivo inteiro novamente (pelo menos do ponto de alteração até o final).
Em alguns casos específicos, você pode fazer melhor que isso -
se todos os seus elementos de dados tiverem o mesmo comprimento e não em uma ordem específica, e você souber o deslocamento daquele que deseja se livrar, copie o último item sobre o que será excluído e trunque o arquivo antes do último item ;
ou você pode simplesmente sobrescrever o bloco de dados com um valor 'são dados incorretos, ignorar' ou manter um sinalizador 'este item foi excluído' nos elementos de dados salvos, para que você possa marcá-lo como excluído sem modificar o arquivo.
Provavelmente isso é um exagero para documentos curtos (algo abaixo de 100 KB?).
Provavelmente, você já obteve uma resposta correta, mas aqui está a minha. Em vez de usar uma lista para coletar dados não filtrados (que readlines()
método faz), eu uso dois arquivos. Um é para reter os dados principais e o segundo é para filtrar os dados quando você exclui uma sequência específica. Aqui está um código:
main_file = open('data_base.txt').read() # your main dataBase file
filter_file = open('filter_base.txt', 'w')
filter_file.write(main_file)
filter_file.close()
main_file = open('data_base.txt', 'w')
for line in open('filter_base'):
if 'your data to delete' not in line: # remove a specific string
main_file.write(line) # put all strings back to your db except deleted
else: pass
main_file.close()
Espero que você ache isso útil! :)
Salve as linhas do arquivo em uma lista, remova da lista a linha que deseja excluir e grave as linhas restantes em um novo arquivo
with open("file_name.txt", "r") as f:
lines = f.readlines()
lines.remove("Line you want to delete\n")
with open("new_file.txt", "w") as new_f:
for line in lines:
new_f.write(line)
Aqui está outro método para remover uma / algumas linhas de um arquivo:
src_file = zzzz.txt
f = open(src_file, "r")
contents = f.readlines()
f.close()
contents.pop(idx) # remove the line item from list, by line number, starts from 0
f = open(src_file, "w")
contents = "".join(contents)
f.write(contents)
f.close()
Você pode usar a
re
biblioteca
Supondo que você seja capaz de carregar seu arquivo txt completo. Você define uma lista de apelidos indesejados e os substitui por uma sequência vazia "".
# Delete unwanted characters
import re
# Read, then decode for py2 compat.
path_to_file = 'data/nicknames.txt'
text = open(path_to_file, 'rb').read().decode(encoding='utf-8')
# Define unwanted nicknames and substitute them
unwanted_nickname_list = ['SourDough']
text = re.sub("|".join(unwanted_nickname_list), "", text)
Para excluir uma linha específica de um arquivo pelo seu número de linha :
Substitua variáveis filename e line_to_delete pelo nome do seu arquivo e o número da linha que você deseja excluir.
filename = 'foo.txt'
line_to_delete = 3
initial_line = 1
file_lines = {}
with open(filename) as f:
content = f.readlines()
for line in content:
file_lines[initial_line] = line.strip()
initial_line += 1
f = open(filename, "w")
for line_number, line_content in file_lines.items():
if line_number != line_to_delete:
f.write('{}\n'.format(line_content))
f.close()
print('Deleted line: {}'.format(line_to_delete))
Exemplo de saída :
Deleted line: 3
for nb, line in enumerate(f.readlines())
Pegue o conteúdo do arquivo, divida-o por nova linha em uma tupla. Em seguida, acesse o número da linha da sua tupla, junte a tupla de resultado e substitua no arquivo.
tuple(f.read().split('\n'))
? (2) "acesse o número da linha da sua tupla" e "junte-se à tupla de resultado" soa bastante misterioso; código Python real pode ser mais compreensível.
fileinput
como descrito por @ jf-sebastian aqui . Parece permitir que você trabalhe linha por linha, através de um arquivo temporário, tudo com umafor
sintaxe simples .