【shell脚本】遍历指定文件夹并获取文件名称及大小

目录


目的:

  • 遍历指定文件夹下的文件,获取其名称、路径、大小(bytes);
  • 主要是三类文件, .h .c .cc共3类文件,其中排除单元测试文件 Test开头的 .h 文件;
  • 使用正则匹配,针对路径不规则的情况;目标文件不放在 src 等规则的目录下;

1. shell 方法

1.1. shell 脚本

1.1.1. 概述

  1. 对于正则表达式的书写,可以借助相关工具,测试语法是否能够正确匹配文本;
    菜鸟教程-正则表达式在线测试工具
  • 脚本

    # 取得目录下(包括子目录) c cc h文件,排除Test*.h文件。
    #!/bin/bash
    # 用途:遍历指定文件夹下的文件,获取文件名称、路径及大小;
    # 文件名后面存在空白字符,导致 .*\.h$ 匹配失效;
    # 
    #site: www.jquerycn.cn
    function ergodic(){
    	for file in `ls $1`
    	do
    	if [ -d $1"/"$file ]
    	then
    		ergodic $1"/"$file
    	else
    		# 定义文件的正则表达式;
    		local hfile='.*\.h\s*$'
    		local tfile='^[^Test].*\.h\s*$'
    		local cfile='.*\.c\s*$'
    		local ccfile="/.*\.cc\s*$/"
    		local path=$1"/"$file
    		local name=$file
    		local size=`du -b --max-depth=1 $path|awk '{print $1}'`
    		# 输出指定文件夹下所有文件的名称、路径、大小,不筛选;
    		# echo $name $path $size
    				# 匹配.h文件,排除以Test开头的.h文件;
    				if [[ ("$name" =~ $hfile)  &&  ("$name" =~ $tfile) ]]
    				then
    					echo $path  $size
    				elif [[ "$name" =~ $cfile ]]
    				then
    					echo $path  $size
    				elif [[ "$name" =~ $ccfile ]]
    				then
    					echo $path  $size
    				else
    					continue
    				fi
    	fi
    	done
    }
    #这个必须要,否则会在文件名中有空格时出错
    IFS=$'\n'
    INIT_PATH="./DBUTILS"
    ergodic $INIT_PATH
    
    # [[]] 运算符只是[]运算符的扩充。能够支持<,>符号运算不需要转义符,它还是以字符串比较大小。
    # 里面支持逻辑运算符:|| &&
    
  • 说明

    • 正则规则

      • 正则运算需要放在 [[正则表达式]] 中,且 = 符号后面紧接 ~
      • 正则表达式不能使用 " " 包裹,单引号也不行;
      • 正则表达式最好定义成变量;
      • 变量使用 "" 进行包裹; – 未测试;
    • 特殊情况

      • $name 在本机操作中,后面出现空白字符,所以使用 \s* 进行了匹配;
  • 失败用例

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存失败,源站可能有防盗链机制,建议将图片保存下来直接上传下上传(i-kzBFW55QZLLUxpbmsvTWFyRvd25AbWFzdGVyL2ltZ3NfZmaT-1626798yX2Jsb2dzLzIwMjAwNzE2MTg1NDQ0LnBuZw?x-oss-process=image/format,pngtps://cdn.jsdelivr.net/gh/VK-Link/Markdown@master/imgs_for_blogs/20200716185444.png)(https://cdn.jsdelivr.net/gh/VK-Link/Markdown@master/imgs_for_blogs/20200716185444.png)]
    以上两个文件 匹配失败,原因未知,此处没有在深究;

1.2. 其他问题

  • 脚本格式问题
    图:
    • 出现 “未预期的符号\r,附近有语法错误;” 的问题;
    • 是因为Windows 上传的脚本在Linux上存在问题,需要进行格式转换;
      yum install dos2unix   # 使用yum源安装 dos2unix包;其他方法也成;
      dos2unix **.sh         # 格式转换;
      

1.3. 笨方法

  • 借助于 catgrep 等命令来实现;

  • 首先在以上shell脚本正则没有通过的情况下;

  • 也可以使用 findgrep 命令来写脚本,本人也是初学,有时间在研究,会的大佬回复里说一下,相互学习;

    # 利用正则表达式 进行匹配;
    sh namesize.sh > te.txt
    vim te.txt
    sh namesize.sh > te.txt
    cat te.txt | grep "/.*\.cc$" > resulthcc.t
    cat te.txt | grep "/.*\.c$" > resulthc.t
    
    sed -e '/\/ut\//d' hresulth.txt > resulthh.txt  //删除ut所在行;
    cat te.txt | grep "/.*\.cc$" > resulthcc.txt
    cat te.txt | grep "/.*\.c$" > resulthc.txt
    
    cat te.txt | grep "/.*\/ut\/.*\.h$" > resulthcc.t
    

参考:

  1. 【shell脚本】递归查找某种类型的文件
  2. linux shell 字符串比较相等、不相等

2. c++语言方法

  • C++ 方法

    #include <io.h>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <iostream>
    
    using namespace std;
    
    
    //获取所有的文件名
    void GetAllFiles( string path, vector<string>& files)
    {
    
    	long   hFile   =   0;
    	//文件信息
    	struct _finddata_t fileinfo;
    	string p;
    	if((hFile = _findfirst(p.assign(path).append("\\*").c_str(),&fileinfo)) !=  -1)
    	{
    		do
    		{
    			if((fileinfo.attrib &  _A_SUBDIR))
    			{
    				if(strcmp(fileinfo.name,".") != 0  &&  strcmp(fileinfo.name,"..") != 0)
    				{
    					files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
    					GetAllFiles( p.assign(path).append("\\").append(fileinfo.name), files );
    				}
    			}
    			else
    			{
    				files.push_back(p.assign(path).append("\\").append(fileinfo.name) );
    			}
    
    		}while(_findnext(hFile, &fileinfo)  == 0);
    
    		_findclose(hFile);
    	}
    
    }
    
    
    int main()
    {
    	string filePath = "D:\\code\\DBUTILS";
    
    	vector<string> files;
    
    	GetAllFiles(filePath, files);
    
    	int size = files.size();
    
    	ofstream oFile;
    	oFile.open("file_size2.csv",ios::out|ios::trunc);
    	oFile<<"组件名称"<<","<<"文件路径名称"<<","<<"文件大小(B)"<<endl;
    	for (int i = 0;i<size;i++)
    	{
    
    		cout<< files[i] << endl;
    		if(files[i].substr(files[i].find_last_of(".") + 1) == "c" 
    			or files[i].substr(files[i].find_last_of(".") + 1) == "cc" 
    			or files[i].substr(files[i].find_last_of(".") + 1) == "h")
    		{
    			string directory = files[i];
    			size_t last_slash_idx = files[i].rfind('\\');
    			if (std::string::npos != last_slash_idx)
    			{
    				directory = files[i].substr(0, last_slash_idx);
    
    				size_t last_slash_idx2 = directory.rfind('\\');
    				directory = directory.substr(last_slash_idx2+1, last_slash_idx);
    
    			}
    			if(directory=="src" or directory=="export" or directory=="common")
    			{
    
    				int handle;
    				const char* p = files[i].data();
    				handle = open(p, 0x0100);
    				long length = filelength(handle);
    				cout<<"file length in bytes:"<<length<<endl;
    				close(handle);
    
    				oFile<<"PROXY"<<","<<files[i]<<","<<length<<endl;
    			}
    
    		}
    
    	}
    	oFile.close();
    	return 0;
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值