You can filter file name or file extension with os module, however it have some limitation. You can use with the two option, which allow you to filter file start with specific file name or end with specific name which refer to the file extension.
1 2 3 4 5 6 7 8 9 10
import os patternfixed=".txt" patternfixed_start="elogfile"
matching_files = [file for file in os.listdir() if file.endswith(patternfixed)] # ['elogfile.txt', 'elogfile2.txt']
matching_files = [file for file in os.listdir() if file.startswith(patternfixed_start)]
From below example I use the fnmatch module which allow me to use the pattern to filter specific file name or file type. So I add am * asterisk which is more flexible to filter file start with elog or file extension as .txt file.
1 2 3 4 5 6 7 8 9 10 11 12
import os, fnmatch
pattern = "elog*" or "*.txt" matching_files = [file for file in os.listdir() if fnmatch.fnmatch(file, pattern)]
# result in list print(matching_files) # ['elogfile', 'elogfile.txt', 'elogfile2', 'elogfile2.txt']
#iterate through list for file in matching_files: print(file)
Summary of listfile
Method
Supports Wildcards
Flexibility Example
Use Case
endswith()
No Matches
files by their exact extension
Get all .txt files
startswith()
No Matches
files by their exact prefix
Get files starting with log\*
fnmatch.fnmatch()
Yes Matches
complex patterns
Get files with names like log\**.txt‵ or ‵*data\*.csv
count matching file
I provide serveral method to achieve it, see which one you perfer. Overall my best otpion is using glob module.
我有用很多不同方式,可以選哪一個妳喜號。
[方法一] os.listdir 跟 len
這個方法我在上面篩選有用過一樣的程式,只是我要算出有找到幾個檔案。
Easy to understand. Directly counts files matching the pattern. Less efficient for large directories with many files
1 2 3 4 5 6 7 8
import os file_pattern_file_startwith = "elog" filelen = len([file for file in os.listdir() if file.startswith(file_pattern)]) matching_files= [file for file in os.listdir() if file.startswith(file_pattern)]
You will have notice I had provided two function which both functionality are the same, one is shorter code using comprehension method, and the other one uses traditional method. In case if you’re not used of using the shorter code, you can reference the traditional way.
1 2 3 4 5 6 7 8
file_pattern_file_startwith = "elog" matching_files=[] filelen = 0 for file in os.listdir(): #Loop through each file in the directory if file.startswith(file_pattern_file_startwith): #Check if the file matches the pattern matching_files.append(file) filelen += 1 print(f'contain {filelen} file, filename: {matching_files}')
可以改成函數 code 比較彈性和乾淨 change the above code into function for more flexibility and cleaner and more readability.
make it into function
1 2 3 4 5 6 7 8 9
def check_file_count_listcomprehension (file_pattern): filename = [file for file in os.listdir() if file.startswith(file_pattern)] filecount = len(filename) return filename,filecount
def check_file_count_withsum(file_pattern): filelen = sum(1 for file in os.listdir() if file.startswith(file_pattern)) # Count matching files filenames = [file for file in os.listdir() if file.startswith(file_pattern)] # List matching files return filelen, filenames # Return both count and filenames file_pattern_file_startwith = "elog"
# Call the function and get results filelen, matching_files = check_file_count_withsum(file_pattern_file_startwith)
Supports advanced wildcard patterns (*, ?, etc.), making it more versatile. Convenient for matching complex patterns. Less efficient for large directories with many files
1 2 3 4 5 6 7 8
import os, glob file_pattern = "elog*"
# Get the list of matching files (debug used) matching_files = glob.glob(file_pattern) filelen=len(matching_files) print(f'contain {filelen} file, filename: {matching_files}') #contain 2 file, filename: ['elogfile', 'elogfile2']
在這邊我們來修改檔名,我會用單一案跟多個檔案。 In this part I wants to show you how to rename with one file and multiple file. Let use any of the method from above to get the file you want.
As you can see the result of the file it matches will return as list datatype, you can try with this print(type(matching_files))#<class 'list'> 如果要修改檔名妳資料類別一定要是 str,篩選結果不會是 str,需要轉成 str,才能改名稱。我們可以用 print(type(matching_files))#<class 'list'> 他會顯示他的資料類別是 list。下面有介紹一些方法如何轉成 str 也可以順利修改檔名。
You need to change it into str to be able to convert. You can either use the index or join method like
get the first name: print(matching_files[0])
convert list to string: ‵filename=””.join(matching_files)‵
Let rename the file using the below code, syntax: rename(original_file_name, new_file_name). In the below example you can see my original file name called elogfile, and change to newelogfile name.
#rename filename try: os.rename(matching_files[0], logfilename) print(f'Renamed {matching_files[0]} to {logfilename}') except Exception as e: print(f"Error renaming file: {e}")
#list current directory filename that contain *logfile* print('='*70) checkfilepattern = "*logfile*" listfiles= [file for file in os.listdir() if fnmatch.fnmatch(file, checkfilepattern)] print(f"List current filename: {listfiles}")
As you can see the filename is been changed, I show the current directory filename with filter file contain logfile which you can see only the elogfile is been change the elogfile2 still the same. This is a basic of rename with SINGLE FILE.
Output:
1 2 3 4 5
contain 1 file, filename: ['elogfile'] Renamed elogfile to newelogfile ====================================================================== List current filename: ['elogfile2', 'newelogfile'] PS C:\Users\test\Desktop\elog_parser\Layer2\singleUe\debug_log_check>
Rename with Multiple File
Now let me show how to change to multiple filename, using the same example from previous, with filename elogfile and elogfile2 and change to newelogfile.
#rename filename for i, file in enumerate(matching_files): try: new_name = f"{logfilename}_{i}" # Generate a unique name for each file os.rename(file, new_name) # Rename each file print(f"Renamed {file} to {new_name}") except Exception as e: print(f"Error renaming file {file}: {e}") print('='*70) checkfilepattern = "newelogfile*" listfiles= [file for file in os.listdir() if fnmatch.fnmatch(file, checkfilepattern)] print(f"List current filename: {listfiles}")
Output:
1 2 3 4 5 6
contain 2 file, filename: ['elogfile', 'elogfile2'] Renamed elogfile to newelogfile_0 Renamed elogfile2 to newelogfile_1 ====================================================================== List current filename: ['newelogfile_0', 'newelogfile_1']