Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 使用fts(3)函数重命名文件和目录。只有第一级被更改_Linux_C - Fatal编程技术网

Linux 使用fts(3)函数重命名文件和目录。只有第一级被更改

Linux 使用fts(3)函数重命名文件和目录。只有第一级被更改,linux,c,Linux,C,这只是一个用下划线替换空格的简单程序。我找到了一个bash脚本,可以完成它,但速度很慢。据我所知,我想要一个深度优先搜索,我想要我的remove_space函数在目录上被后置调用(在备份的过程中)。我是否正确理解术语?现在的情况是,我必须多次调用该程序,因为它需要更改所有的名称。我认为,因为它在返回输入目录时更改了目录名的前序,所以它找不到它,因为它正在查找旧名称。您知道如何在Postorder中的目录上调用我的函数吗 提前谢谢 int main(int argc, char *argv[])

这只是一个用下划线替换空格的简单程序。我找到了一个bash脚本,可以完成它,但速度很慢。据我所知,我想要一个深度优先搜索,我想要我的remove_space函数在目录上被后置调用(在备份的过程中)。我是否正确理解术语?现在的情况是,我必须多次调用该程序,因为它需要更改所有的名称。我认为,因为它在返回输入目录时更改了目录名的前序,所以它找不到它,因为它正在查找旧名称。您知道如何在Postorder中的目录上调用我的函数吗

提前谢谢

int main(int argc, char *argv[]) {
char * const *old_name = (argv + 1);
int opts = 0;
FTS *ftsp;
FTSENT *scan;

if (argc < 2) {
    fprintf(stderr, "usage: %s <dir path>\n", *argv);
    exit(1);
}

opts |= (FTS_PHYSICAL | FTS_SEEDOT | FTS_XDEV);

ftsp = fts_open(old_name, opts, NULL);

while ((scan = fts_read(ftsp)) != NULL) {
    if (scan->fts_info == FTS_DOT)
        continue;
    remove_space(scan->fts_name);
    printf("%s\n", scan->fts_name);
}

fts_close(ftsp);
return 0;
}

int remove_space(const char *old_str) {
char new_str[strlen(old_str)];
int i = 0;
int j = 0;

while (*(old_str + i)) {
    if (isalnum(*(old_str + i))) {
        while (*(old_str + i)) {

            if (*(old_str + i) == SPACE)
                *(new_str + j) = UNDER_SCORE;
            else
                *(new_str + j) = *(old_str  + i);
            i++;
            j++;
        }
    } else {
        i++;
    }
}
*(new_str + j) = '\0';
rename(old_str, new_str);
return 0;
}
intmain(intargc,char*argv[]){
char*const*old_name=(argv+1);
int opts=0;
FTS*ftsp;
FTSENT*扫描;
如果(argc<2){
fprintf(标准,“用法:%s\n”,*argv);
出口(1);
}
opts |=(FTS|U物理| FTS|U西多特| FTS|U XDEV);
ftsp=fts_打开(旧名称,选项,空);
而((扫描=fts_读取(ftsp))!=NULL){
如果(扫描->fts\U信息==fts\U点)
继续;
删除_空间(扫描->fts_名称);
printf(“%s\n”,扫描->fts\u名称);
}
fts_close(ftsp);
返回0;
}
int remove_space(const char*old_str){
char new_str[strlen(old_str)];
int i=0;
int j=0;
而(*(旧街+i)){
如果(isalnum(*(旧街+i))){
而(*(旧街+i)){
如果(*(旧的字符串+i)=空格)
*(新的_str+j)=低于_分数;
其他的
*(新街+j)=*(旧街+i);
i++;
j++;
}
}否则{
i++;
}
}
*(新的_str+j)='\0';
重命名(旧的、新的);
返回0;
}

如手册页所述,在*fts_read*:

访问目录(可读且不会导致循环) 至少两次,一次按前序,一次按后序

因此,一种方法是测试这是否是一个目录,并在第一次遇到它时跳过它

手册页上的*fts_集*中描述了另一种方法,并再次使用选项fts_:

通常用于postorder目录访问,它会导致 要重新访问的目录(包括前序和后序) 就像它所有的后代一样


顺便说一句,如果性能是您的问题,您可以使用*fts_children*,使用fts_name only选项。同样感谢您,检查FTS_DP可确保我只在postorder中编辑目录。这对我的实施产生了重大影响。