linux bash shell:最方便的字符串大小写转换(lowercase/uppercase conversion)

本文介绍Bash4.0以上版本中使用${parameter,,pattern}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于字符串大小写转换,是写 linux 脚本经常干的事儿,所以总想找个方便的方法让我少打点字儿,搜索国内的中文资源,网上也能找到很多关于这个帖子,介绍的方法都差不多,用typeset是最简单的方法了,但我觉得还是不够简单,因为需要多定义一个变量。

google上找到这个stackoverflow上的帖子,才知道Bash 4.0以上版本有更好的办法:

《How to convert a string to lower case in Bash?》

就是${parameter,,pattern},${parameter^^pattern}表达式,表达不会改变原来变量的值

#! /bin/bash
# 注意:脚本第一行一定要注明脚本解释器是bash.不能是sh,或dash
# 因为sh软连接有可能指向的是dash
var="Hello,Word"
# 把变量中的第一个字符换成大写 
echo ${var^} 
# 把变量中的所有小写字母,全部替换为大写
echo ${var^^}   
# 把变量中的第一个字符换成小写
echo ${var,}
# 把变量中的所有大写字母,全部替换为小写
echo ${var,,}

Bash 4.0是2009年发布的版本,现在的应用已经很广泛了,我现在用的ubuntu 16默认安装的就是bash 4.3,centos 6.5下默认安装的是4.1.所以只要不是太老的linux版本,都不会有兼容性问题。

关于${parameter,,pattern},${parameter^^pattern}表达式更全面的说明参见下面Bash的官方手册:

《Bash Reference Manual》

/* * file char_dev.c * brief 注册字符设备. * * author Gaoziyue * version 1.0.0 * date 7Aug25 * * history \arg 1.0.0, 7Aug25, Gaoziyue, Create the file. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/uaccess.h> #include <linux/device.h> #include <linux/slab.h> /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ /*设备名称*/ #define DEVICE_NAME "char_dev" /*设备类*/ #define CLASS_NAME "char_class" /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* EXTERN_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_PROTOTYPES */ /**************************************************************************************************/ static int char_open(struct inode* inode, struct file* file); static int char_release(struct inode* inode, struct file* file); static ssize_t char_write(struct file* file, const char __user* buf, size_t count, loff_t* offset); static int __init char_init(void); static void __exit char_exit(void); /**************************************************************************************************/ /* VARIABLES */ /**************************************************************************************************/ static int major_num = 0;/*主设备号*/ static struct class* char_class = NULL; static struct device* char_device = NULL; static struct cdev char_cdev;/*字符设备结构*/ static int cap = 0;/*模块参数,默认0,不转换大写*/ /**************************************************************************************************/ /* FUNCTIONS */ /**************************************************************************************************/ module_param(cap, int, S_IRUGO);/*定义模块参数cap,类型int,权限为只读*/ MODULE_PARM_DESC(cap, "Enable uppercase conversion (1=enable)");/*参数描述*/ /* * @brief 字符设备打开函数. * @param[in] inode 指向设备文件的inode结构(索引节点),包含设备号、文件属性等元数据. * @param[in] file 指向文件结构体,表示此次打开操作的上下文. * @return 返回0表示成功,返回负值表示错误. */ static int char_open(struct inode* inode, struct file* file) { printk(KERN_INFO "Char device opened\n"); return 0; } /* * @brief 字符设备关闭函数. * @param[in] inode 指向设备文件的inode结构(索引节点),包含设备号、文件属性等元数据. * @param[in] file 指向文件结构体,表示此次打开操作的上下文. * @return 返回0表示成功,返回负值表示错误. */ static int char_release(struct inode* inode, struct file* file) { printk(KERN_INFO "Char device closed\n"); return 0; } /* * @brief 写设备函数. * @param[in] file 当前打开的文件结构体. * @param[in] buf 待写入的原始数据指针. * @param[in] count 请求写入的字节数. * @param[in/out] offset 指向文件当前位置偏移量的指针. * @return 成功时返回写入字节数;失败时返回负错误码. */ static ssize_t char_write(struct file* file, const char __user* buf, size_t count, loff_t* offset) { char* kernel_buf = kmalloc(count + 1, GFP_KERNEL);/*分配内核缓冲区(+1为结尾的'\0')*/ if (NULL == kernel_buf) { printk(KERN_ALERT "Memory allocation failed\n"); return -ENOMEM; } /*从用户空间复制数据*/ if (copy_from_user(kernel_buf, buf, count)) { kfree(kernel_buf); return -EFAULT; } kernel_buf[count] = '\0'; /*确保字符串结尾*/ /*大小写转换*/ if (cap) { int i = 0; for (i = 0; i < count; i++) { if (kernel_buf[i] >= 'a' && kernel_buf[i] <= 'z') { kernel_buf[i] -= 32; /*转换为大写*/ } } } /*打印处理后的内容*/ printk(KERN_INFO "Received: %s\n", kernel_buf); kfree(kernel_buf); return count; } /* * brief 文件操作结构. */ static struct file_operations fops = { .owner = THIS_MODULE, /*指向当前模块*/ .open = char_open, /*打开函数*/ .release = char_release,/*关闭函数*/ .write = char_write, /*写函数*/ }; /* * brief 模块初始化. */ static int __init char_init(void) { /*分配设备号*/ if (alloc_chrdev_region(&major_num, 0, 1, DEVICE_NAME) < 0) { printk(KERN_ALERT "Failed to allocate device number\n"); return -1; } /*创建设备类*/ char_class = class_create(THIS_MODULE, CLASS_NAME); if (IS_ERR(char_class)) { unregister_chrdev_region(major_num, 1); /*撤销设备号*/ printk(KERN_ALERT "Failed to create device class\n"); return PTR_ERR(char_class); } /*创建设备*/ char_device = device_create(char_class, NULL, major_num, NULL, DEVICE_NAME); if (IS_ERR(char_device)) { class_destroy(char_class); /*销毁类*/ unregister_chrdev_region(major_num, 1); /*撤销设备号*/ printk(KERN_ALERT "Failed to create device\n"); return PTR_ERR(char_device); } /*初始化字符设备*/ cdev_init(&char_cdev, &fops); if (cdev_add(&char_cdev, major_num, 1) < 0) { device_destroy(char_class, major_num); /*销毁设备*/ class_destroy(char_class); /*销毁类*/ unregister_chrdev_region(major_num, 1); /*撤销设备号*/ printk(KERN_ALERT "Failed to add cdev\n"); return -1; } printk(KERN_INFO "Char device loaded with cap=%d\n", cap); return 0; } /* * brief 模块退出. */ static void __exit char_exit(void) { cdev_del(&char_cdev); /*删除字符设备*/ device_destroy(char_class, major_num); /*销毁设备*/ class_destroy(char_class); /*销毁类*/ unregister_chrdev_region(major_num, 1); /*撤销设备号*/ printk(KERN_INFO "Char device unloaded\n"); } module_init(char_init); /*指定初始化函数*/ module_exit(char_exit); /*指定退出函数*/ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ma Qianyi"); MODULE_DESCRIPTION("Character device with case conversion"); 这个是我的代码,我想知道我现在怎么做才能对字符设备进行写操作,内核会将写入该字符设备的内容打印出来 可以正常安装卸载内核模块 内核模块可以带参数,cap=1时输入全转为大写输出
最新发布
08-09
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值