Linux 命令用于备份文件,并在文件名后附加当天的日期

Linux 命令用于备份文件,并在文件名后附加当天的日期

是否可以运行cp命令来创建文件的备份并将其重命名为今天的日期/时间

例如:

  • foo.txt
  • foo.txt.2012.03.03.12.04.06

答案1

cp -p foo.txt foo.txt.`date +%Y.%m.%d.%H.%M.%S`

答案2

cp -p foo.txt foo.txt.`date -I`

这将把日期转换为 ISO 格式 yyyy-mm-dd

答案3

将以下代码片段复制到 mkcp.c 并使用以下代码进行编译

  • # gcc -o mkcp mkcp.c在 Linux 或
  • # cl mkcp.c在 Windows® 上。

# ./mkcp mkcp.c然后运行cp命令并创建副本,例如mkcp.c_sav_2018-01-04

#ifdef __linux__ 
#include<dirent.h>
#endif
#include<errno.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h> // mkdir
#include<sys/types.h>
#include<time.h>
#ifdef __linux__ 
#include<unistd.h>
#endif
#if defined(_MSC_VER)
#include<BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif

#if defined(__TINYC__)
#include "./dirent.h"

typedef ptrdiff_t handle_type; /* C99's intptr_t not sufficiently portable */

struct DIR
{
    handle_type         handle; /* -1 for failed rewind */
    struct _finddata_t  info;
    struct dirent       result; /* d_name null iff first time */
    char                *name;  /* null-terminated char string */
};

DIR *opendir(const char *name) {
    DIR *dir = 0;

    if(name && name[0])
    {
    size_t base_length = strlen(name);
    const char *all = /* search pattern must end with suitable wildcard */
    strchr("/\\", name[base_length - 1]) ? "*" : "/*";

    if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
       (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
    {
    strcat(strcpy(dir->name, name), all);

    if((dir->handle =
    (handle_type) _findfirst(dir->name, &dir->info)) != -1)
    {
    dir->result.d_name = 0;
    }
    else /* rollback */
    {
    free(dir->name);
    free(dir);
    dir = 0;
    }
    }
    else /* rollback */
    {
    free(dir);
    dir   = 0;
    errno = ENOMEM;
    }
    }
    else
    {
    errno = EINVAL;
    }

    return dir;
}

int closedir(DIR *dir)
{
    int result = -1;

    if(dir)
    {
    if(dir->handle != -1)
    {
    result = _findclose(dir->handle);
    }

    free(dir->name);
    free(dir);
    }

    if(result == -1) /* map all errors to EBADF */
    {
    errno = EBADF;
    }

    return result;
}

struct dirent *readdir(DIR *dir)
{
    struct dirent *result = 0;

    if(dir && dir->handle != -1)
    {
    if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
    {
    result         = &dir->result;
    result->d_name = dir->info.name;
    }
    }
    else
    {
    errno = EBADF;
    }

    return result;
}

#endif

int cp(const char *from, const char *to) {
    int fd_to, fd_from;
    char buf[4096];

    ssize_t nread;
    int saved_errno;

    fd_from = open(from, O_RDONLY);
    if (fd_from < 0) {
    fprintf(stderr,"Error opening input file %s.\n", from);        
    return -1;
    }

    fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0666);
    if (fd_to < 0) {
    fprintf(stderr,"Error opening output file %s.\n", to);
    fprintf(stderr,"Most probably an output file %s exists already.\n", to);
    goto out_error;
    }

    while (nread = read(fd_from, buf, sizeof buf), nread > 0) {
    char *out_ptr = buf;
    ssize_t nwritten;

    do {
    nwritten = write(fd_to, out_ptr, nread);

    if (nwritten >= 0) {
        nread -= nwritten;
        out_ptr += nwritten;
    } else if (errno != EINTR) {
        goto out_error;
    }
    } while (nread > 0);
    }

    if (nread == 0) {
    if (close(fd_to) < 0) {
    fd_to = -1;
    goto out_error;
    }
    close(fd_from);

    /* Success! */
    return 0;
    }

  out_error:
    saved_errno = errno;

    close(fd_from);
    if (fd_to >= 0) close(fd_to);

    errno = saved_errno;
    return -1;
}

mode_t getumask() {
    mode_t mask = umask(0);
    umask (mask);
    return mask;
}

void help(char *this_program) {
    printf("usage:  %s [options] fts\n", this_program);
    printf("options:\n");
    printf("-h,--help       Show this help.\n");
    printf("fts             File or folder to save.\n");
}

void rmkdr(const char *dr) {
    #ifdef __linux__ 
    if (mkdir(dr,0777-getumask()) == -1) {
    // perror(argv[0]);
    fprintf(stderr,"Failed to create the folder %s.\n", dr);
    fprintf(stderr,"Most likely a folder %s exists already.\n", dr);
    fprintf(stderr,"Stop.\n");
    exit(EXIT_FAILURE);
    }
    #endif
    #if defined(__TINYC__)
    if (mkdir(dr) == -1) {
    // perror(argv[0]);
    fprintf(stderr,"Failed to create the folder %s.\n", dr);
    fprintf(stderr,"Most likely a folder %s exists already.\n", dr);
    fprintf(stderr,"Stop.\n");
    exit(EXIT_FAILURE);
    }
    #endif
}

int lmdir(const char *dr, char *ndr) {
    char *oldpath;
    char *newpath;
    DIR *dir;
    int res;
    size_t newneeded, oldneeded;
    struct dirent *entry;

    if(!(dir = opendir(dr))) {
    fprintf(stderr, "Argument is not a folder.\n");
    fprintf(stderr,"Stop.\n");
    exit(EXIT_FAILURE);
    }

    while((entry = readdir(dir)) != NULL) {
    #ifdef __linux__
    newneeded = snprintf(NULL, 0, "%s/%s", ndr,entry->d_name) + 1;      
    oldneeded = snprintf(NULL, 0, "%s/%s", dr,entry->d_name) + 1;
    newpath = (char *) malloc(newneeded);
    oldpath = (char *) malloc(oldneeded);
    snprintf(newpath, newneeded, "%s/%s",ndr,entry->d_name);
    snprintf(oldpath, oldneeded, "%s/%s",dr,entry->d_name);
    if(entry->d_type == DT_DIR) {
        if(strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0) continue;
        rmkdr(newpath);
        lmdir(oldpath, newpath);
    } else if(entry->d_type == DT_REG) {
        res=cp(oldpath,newpath);    
        if(res!=0) {
            exit(EXIT_FAILURE);
        }

    }       
    #endif
    #if defined(__TINYC__)
    newneeded = snprintf(NULL, 0, "%s/%s", ndr,entry->d_name) + 1;      
    oldneeded = snprintf(NULL, 0, "%s/%s", dr,entry->d_name) + 1;
    newpath = malloc(newneeded);
    oldpath = malloc(oldneeded);
    snprintf(newpath, newneeded, "%s/%s",ndr,entry->d_name);
    snprintf(oldpath, oldneeded, "%s/%s",dr,entry->d_name);
    if(opendir(oldpath) != NULL) {
        if(strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0) continue;
        rmkdr(newpath);
        lmdir(oldpath, newpath);
    } else {
        res=cp(oldpath,newpath);    
        if(res!=0) {
            fprintf(stderr, "Exit failure.\n");
            free(newpath);          
        free(oldpath);   
            exit(EXIT_FAILURE);
        }
    }
    #endif
    free(newpath);          
    free(oldpath);        
    }
}

int main(int argc, char *argv[]) {
char *cpstr;
char *drstr;
char *dtstr;
DIR *dir;
int i, res=0;
time_t t = time(NULL);

struct dirent *dptr;
struct tm tml;
tml = *localtime(&t);

for(i=0; i<argc; i++) {
    if(strcmp(argv[i],"--help")==0||strcmp(argv[i],"-h")==0) {
    help(argv[0]);
    return(0);
    }

}

if(argc<2) {
    help(argv[0]);
    return(1);
}

if(argv[1][strlen(argv[1])-1]=='/') {
    drstr=(char *) malloc((strlen(argv[1]))*sizeof(char));
    snprintf(drstr,strlen(argv[1]),"%s",argv[1]);
} else {
    drstr=(char *) malloc(1+strlen(argv[1])*sizeof(char));
    snprintf(drstr,1+strlen(argv[1]),"%s",argv[1]);
}

dtstr = (char *) malloc(12*sizeof(char));
snprintf(dtstr, 11, "%d-%02d-%02d", tml.tm_year + 1900, tml.tm_mon + 1, tml.tm_mday);

cpstr = (char *) malloc((1+strlen(dtstr)+strlen(drstr)+strlen("_sav_"))*sizeof(char));
strcpy(cpstr, drstr);
strcat(cpstr, "_sav_");
strcat(cpstr, dtstr);

if(!(dir = opendir(argv[1]))) {
    res=cp(argv[1],cpstr);
    if(res!=0) {
    fprintf(stderr,"Stop.\n");
    exit(EXIT_FAILURE);
    }
    fprintf(stdout, "Output to be written to: %s.\n", cpstr);
    fprintf(stdout, "Success.\n");
    free(cpstr);
    free(drstr);
    free(dtstr);
    exit(EXIT_SUCCESS);
}

rmkdr(cpstr);
lmdir(drstr, cpstr);

if(res==0) {
    printf("Output to be written to: %s.\n", cpstr);
    printf("Success.\n");
}
free(cpstr);
free(drstr);
free(dtstr);
return(0);
}

注意:mkcp实际上会检查要写入的文件是否已经存在。mkcp在这种情况下将停止。因此,任何数据丢失的风险都被最小化。

答案4

cp foo{,$(date -I)}

如果你真正想要的是使用 sed 快速编辑,可以使用类似sed -i.$(date -I) -e ...

输出格式date -I如下2018-12-31

干杯,卡梅伦

相关内容