GNU/Linux >> Belajar Linux >  >> Linux

Cara Memodifikasi File Di Tempat?

Saya memiliki file yang cukup besar (35Gb), dan saya ingin memfilter file ini di tempat (yaitu saya tidak memiliki cukup ruang disk untuk file lain), khususnya saya ingin mengambil dan mengabaikan beberapa pola — apakah ada cara untuk lakukan ini tanpa menggunakan file lain?

Katakanlah saya ingin memfilter semua baris yang berisi foo: misalnya…

Jawaban yang Diterima:

Pada tingkat panggilan sistem, ini harus dimungkinkan. Sebuah program dapat membuka file target Anda untuk menulis tanpa memotongnya dan mulai menulis apa yang dibacanya dari stdin. Saat membaca EOF, file output dapat terpotong.

Karena Anda memfilter baris dari input, posisi penulisan file output harus selalu lebih kecil dari posisi baca. Ini berarti Anda tidak boleh merusak input Anda dengan output baru.

Namun, menemukan program yang melakukan ini adalah masalahnya. dd(1) memiliki opsi conv=notrunc yang tidak memotong file output saat terbuka, tetapi juga tidak memotong di akhir, meninggalkan konten file asli setelah konten grep (dengan perintah seperti grep pattern bigfile | dd of=bigfile conv=notrunc )

Karena sangat sederhana dari perspektif panggilan sistem, saya menulis sebuah program kecil dan mengujinya pada sistem file loopback penuh (1MiB) kecil. Itu melakukan apa yang Anda inginkan, tetapi Anda benar-benar ingin menguji ini dengan beberapa file lain terlebih dahulu. Akan selalu berisiko menimpa file.

menimpa.c

/* This code is placed in the public domain by camh */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char **argv)
{
        int outfd;
        char buf[1024];
        int nread;
        off_t file_length;

        if (argc != 2) {
                fprintf(stderr, "usage: %s <output_file>n", argv[0]);
                exit(1);
        }
        if ((outfd = open(argv[1], O_WRONLY)) == -1) {
                perror("Could not open output file");
                exit(2);
        }
        while ((nread = read(0, buf, sizeof(buf))) > 0) {
                if (write(outfd, buf, nread) == -1) {
                        perror("Could not write to output file");
                        exit(4);
                }
        }
        if (nread == -1) {
                perror("Could not read from stdin");
                exit(3);
        }
        if ((file_length = lseek(outfd, 0, SEEK_CUR)) == (off_t)-1) {
                perror("Could not get file position");
                exit(5);
        }
        if (ftruncate(outfd, file_length) == -1) {
                perror("Could not truncate file");
                exit(6);
        }
        close(outfd);
        exit(0);
}

Anda akan menggunakannya sebagai:

grep pattern bigfile | overwrite bigfile

Saya kebanyakan memposting ini untuk dikomentari orang lain sebelum Anda mencobanya. Mungkin orang lain mengetahui program yang melakukan hal serupa yang lebih teruji.

Terkait:Siapa pemilik file jika file dibuat menggunakan perintah Sudo?
Linux
  1. Cara Mudah Menyembunyikan File dan Direktori di Linux

  2. Cara Cerdas Untuk Mendefragmentasi Sistem File yang Gemuk?

  3. Cara portabel untuk mendapatkan ukuran file (dalam byte) di shell?

  1. cara tercepat mengonversi file yang dibatasi tab ke csv di linux

  2. Cara paling efisien untuk menyalin file di Linux

  3. Apakah ada cara untuk memotong file NETCDF?

  1. Cara mengurutkan file di tempat

  2. Cara memodifikasi file DTB kernel

  3. Apakah ada cara untuk mengubah pintasan di tengah malam komandan?