有没有办法在不知道其全名的情况下使用open()
打开文件?
通过接受正则表达式作为输入,linux shell提供了一种简单的方法(在某种意义上)
例如,如果您有一个包含文件的文件夹:
a.out file1 file2 file3 file4 file.txt test
并且您希望仅列出前缀为file
的文件,您可以通过以下方式执行此操作:
$ ls file*
file1 file2 file3 file4 file.txt
或者:
$ ls file[1-9]
file1 file2 file3 file4
仅列出编号的文件,依此类推......
每当我的程序启动时,我都需要打开相同的文件
问题是,它需要打开的文件格式为:X*Y
,意味着它以X
开头,以Y
结尾,但它可能介于两者之间。
例如,它可以是X-Toshiba_12.45y9-Y
,也可以是X-Dell-5.44s-Y
我希望能够在不考虑模型的情况下打开此文件
该文件可能与该文件夹中的其他文件一起存在,但X
前缀和Y
后缀是唯一的。
我可以迭代该文件夹中的文件并尝试通过匹配字符串找到我的文件,但我宁愿避免它。
有没有办法以某种方式为open()
提供正则表达式?
答案 0 :(得分:4)
这些不是regular expressions!你在谈论glob patterns。
您可以使用POSIX.1-2001 glob()
函数将glob模式(如*.*
或foo-*.?a*
或*.[a-z]*
等)扩展为数组与给定模式匹配的文件名/路径名(从当前工作目录开始,除非模式指定绝对路径)。这基本上是大多数shell在扩展文件名模式时使用的。
如果你非常喜欢使用正则表达式指定文件名(比如说,你需要find
- 类型行为,但使用正则表达式),请使用SUSv4 nftw()
函数遍历目录树 - 它甚至可以处理边角情况,例如描述符少于树深度,或者在树遍历时修改,重命名或移动文件,以及POSIX regex函数来过滤文件名。注意:regcomp()
和regexec()
等内置于POSIX.1-2001支持C库,其中包括Linux的所有当前C库实现。根本不需要外部库。
这让我很伤心使用opendir()
/ readdir()
遍历一个目录树,当nftw()
是可用的和更聪明和更健壮的示例代码看到。只需定义_XOPEN_SOURCE 700
和_POSIX_C_SOURCE 200809L
以获得Linux和许多* BSD变体中的所有这些优秀功能。
答案 1 :(得分:1)
检查此示例
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
int
startswith(const char *const haystack, const char *const needle)
{
size_t haystackLength;
size_t needleLength;
if ((haystack == NULL) || (needle == NULL))
return 0;
haystackLength = strlen(haystack);
needleLength = strlen(needle);
if (haystackLength < needleLength)
return 0;
return (memcmp(haystack, needle, needleLength) == 0);
}
int
endswith(const char *const haystack, const char *const needle)
{
size_t haystackLength;
size_t needleLength;
if ((haystack == NULL) || (needle == NULL))
return 0;
haystackLength = strlen(haystack);
needleLength = strlen(needle);
if (haystackLength < needleLength)
return 0;
return (memcmp(haystack + haystackLength - needleLength, needle, needleLength) == 0);
}
void
searchdir(const char *const directory, const char *const starts, const char *const ends)
{
DIR *dir;
struct dirent *entry;
dir = opendir(directory);
if (dir == NULL)
return;
while ((entry = readdir(dir)) != NULL)
{
struct stat statbuf;
char filepath[PATH_MAX];
size_t length;
const char *name;
name = entry->d_name;
if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0))
continue;
length = snprintf(filepath, sizeof(filepath), "%s/%s", directory, name);
if (length >= sizeof(filepath))
{
fprintf(stderr, "unexpected error\n");
closedir(dir);
return;
}
if (stat(filepath, &statbuf) == -1)
{
fprintf(stderr, "cannot stat `%s'\n", filepath);
continue;
}
/* if the entry is a directory, probably recures */
if (S_ISDIR(statbuf.st_mode) != 0)
saerchdir(filepath, starts, ends);
/* or just, continue? */
/* The file name does not match */
if ((startswith(name, starts) == 0) || (endswith(name, ends) == 0))
continue;
/* Do whatever you want with the file */
fprintf(stdout, "%s\n", filepath);
}
closedir(dir);
}
int
main(int argc, char **argv)
{
if (argc < 4)
{
fprintf(stderr, "usage: %s directory startpattern endpattern\n", argv[0]);
fprintf(stderr, "\tex. %s /home/${USER} X Y\n", argv[0]);
return -1;
}
searchdir(argv[1], argv[2], argv[3]);
return 0;
}
对文件执行任何操作,可以将其推送到char *
数组,将函数指针传递给函数并在文件路径上执行该函数。