Linux下basename使用及代码实现

在 Linux操作系统上,basename 命令从文件名中去除目录信息和后缀。这在要从长文件路径中提取文件名是特别有用。

本页介绍了 basename 的命令的使用及basename命令代码实现。

basename命令用法

basename 命令有两种语法。 第一个涉及后缀

第二个允许您添加选项:

这里要说一下,不能将选项与后缀结合使用。 暂时不要混淆。

使用带有文件路径的 basename 命令将给出文件名:

自己写的basename命令,用来试验一下,是否跟linux自带的命令是否输出一致:

看效果就知道,我们输出是一样的。

basename 命令实际上非常简单。 它并不真正识别文件路径。 它只是查找斜杠 (/) 并打印最后一个斜杠之后的内容。

来看看代码是如何实现的。

char *base_name (char const *name)
{char const *base = last_component (name);size_t length;/* 如果没有最后一个组件,则名称是文件系统根目录或空字符串。  */if (! *base)return strndup (name, base_len(name));/* 将一系列尾部斜杠折叠成一个。 */length = base_len (base);if (ISSLASH (base[length]))length++;/* 在带有驱动器号的系统上,“a/b:c”必须返回“./b:c”而不是而不是“b:c”以避免与驱动器号混淆。 在系统上使用纯 POSIX 语义,这不是问题。  */if (FILE_SYSTEM_PREFIX_LEN (base)){char *p = (char *)malloc (length + 3);p[0] = '.';p[1] = '/';memcpy (p + 2, base, length);p[length + 2] = '\0';return p;}/* 最后,复制基本名称。  */return strndup(base, length);
}

例如,如果我通过删除文件名来运行上面的示例,它将产生以下结果。


linux自带的basename命令运行,猜的没有错的话,运行也是跟我们写的一样。

删除带后缀的文件扩展名

bashname 命令的主要用途是从文件路径中提取文件名。 您还可以在提取文件名时删除文件扩展名。

只需提及您要从输出末尾删除的内容。 因此,假设您想从 test.txt 中删除 .txt。 只需在 basename 命令的末尾添加它:

我们自己写的basename命令输出结果:

linux自带的basename效果:

从输入的最终组件的末尾删除后缀。 如果没有真正弄清楚文件的扩展名。 如果您提供 html(不带点)而不是 .html,您将得到“文件名”(末尾带点)。

linux自带的basename效果:

此外,如果您提供的后缀不在组件的末尾,则输出将保持为没有后缀。

与多个路径一起使用

使用选项 -a,您可以同时使用多个路径。

basename命令简易代码实现

size_t base_len (char const *name)
{size_t len;size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);for (len = strlen (name);  1 < len && ISSLASH (name[len - 1]);  len--)continue;if (len == 1&& ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])return 2;if (prefix_len&& len == prefix_len && ISSLASH (name[prefix_len]))return prefix_len + 1;return len;
}char *base_name (char const *name)
{char const *base = last_component (name);size_t length;/* 如果没有最后一个组件,则名称是文件系统根目录或空字符串。  */if (! *base)return strndup (name, base_len(name));/* 将一系列尾部斜杠折叠成一个。 */length = base_len (base);if (ISSLASH (base[length]))length++;if (FILE_SYSTEM_PREFIX_LEN (base)){char *p = (char *)malloc (length + 3);p[0] = '.';p[1] = '/';memcpy (p + 2, base, length);p[length + 2] = '\0';return p;}/* 最后,复制基本名称。  */return strndup(base, length);
}/*如果存在 NAME 末尾的 SUFFIX,则删除它,除非 NAME完全由后缀组成。 */static void remove_suffix (char *name, const char *suffix)
{char *np;const char *sp;np = name + strlen (name);sp = suffix + strlen (suffix);while (np > name && sp > suffix)if (*--np != *--sp)return;if (np > name)*np = '\0';
}static void perform_basename (const char *string, const char *suffix, bool use_nuls)
{char *name = base_name (string);strip_trailing_slashes (name);if (suffix && IS_RELATIVE_FILE_NAME (name) && ! FILE_SYSTEM_PREFIX_LEN (name))remove_suffix (name, suffix);fputs (name, stdout);putchar (use_nuls ? '\0' : '\n');free (name);
}int main(int argc, char **argv)
{bool multiple_names = false;//optind: argv的当前索引值while (true){int c = getopt(argc, argv, "+a");if (c == -1)break;switch (c){case 'a':multiple_names = true;break;default:break;}}if (argc < optind + 1){printf("missing operand\n");return -1;}if (!multiple_names && optind + 2 < argc){printf("extra operand --> %s\n",strdup(argv[optind + 2]));return -1;}if (multiple_names){for (; optind < argc; optind++)perform_basename (argv[optind], NULL, false);}elseperform_basename(argv[optind],optind + 2 == argc ? argv[optind + 1] : NULL, false);return 0;
}

basename代码实现了获取路径中的文件名或路径名,还可以对末尾字符进行删除。

欢迎关注微信公众号【程序猿编码】,欢迎添加本人微信号(17865354792),交个朋友,咱们一起学习进步!

本文链接:https://my.lmcjl.com/post/6104.html

展开阅读全文

4 评论

留下您的评论.