Tôi có một thư mục với một loạt các tập tin bên trong: eee2314, asd3442... và eph.
Tôi muốn loại bỏ tất cả các file bắt đầu bằng ephvới globchức năng.
Tôi làm nó như thế nào?
Tôi có một thư mục với một loạt các tập tin bên trong: eee2314, asd3442... và eph.
Tôi muốn loại bỏ tất cả các file bắt đầu bằng ephvới globchức năng.
Tôi làm nó như thế nào?
Câu trả lời:
Các quy tắc mẫu cho cầu không phải là biểu thức chính quy. Thay vào đó, chúng tuân theo các quy tắc mở rộng đường dẫn Unix tiêu chuẩn. Chỉ có một số ký tự đặc biệt: hai ký tự đại diện khác nhau và phạm vi ký tự được hỗ trợ [từ cầu ].
Vì vậy, bạn có thể loại trừ một số tệp có mẫu.
Ví dụ: để loại trừ các tệp kê khai (tệp bắt đầu bằng _) với hình cầu, bạn có thể sử dụng:
files = glob.glob('files_path/[!_]*')
ephnhưng có thể bắt đầu bằng bất kỳ thứ gì khác. [!e][!p][!h]sẽ lọc ra các tệp bắt đầu bằng eeeví dụ.
Bạn có thể trừ các bộ:
set(glob("*")) - set(glob("eph*"))
set(glob("*")) - set(glob("eph*")) (và thông báo * ở cuối "eph *")
list(set(glob("*")) - set(glob("eph")))
Bạn không thể loại trừ các mẫu bằng globhàm, các hình cầu chỉ cho phép các mẫu bao gồm . Cú pháp bóng bẩy rất hạn chế (thậm chí một [!..]lớp ký tự phải khớp với một ký tự, vì vậy nó là một mẫu bao gồm cho mọi ký tự không có trong lớp).
Bạn sẽ phải thực hiện lọc của riêng mình; một cách hiểu danh sách thường hoạt động tốt ở đây:
files = [fn for fn in glob('somepath/*.txt')
if not os.path.basename(fn).startswith('eph')]
iglobở đây để tránh việc lưu trữ danh sách đầy đủ trong bộ nhớ
iglobtạo ra danh sách nào ; tất cả những gì bạn làm là lười biếng đánh giá bộ lọc. Nó sẽ không giúp giảm dung lượng bộ nhớ.
os.listdir()kết quả được lưu trong bộ nhớ khi bạn lặp lại. Nhưng somepath/*.txtphải đọc tất cả các tên tệp trong một thư mục trong bộ nhớ, sau đó giảm danh sách đó xuống chỉ những tên phù hợp.
glob.glob(x) = list(glob.iglob(x)). Không có nhiều chi phí nhưng vẫn tốt để biết.
Cuối trò chơi nhưng bạn có thể chỉ cần áp dụng một con trăn filtervào kết quả của một glob:
files = glob.iglob('your_path_here')
files_i_care_about = filter(lambda x: not x.startswith("eph"), files)
hoặc thay thế lambda bằng một tìm kiếm regex thích hợp, v.v.
CHỈNH SỬA: Tôi vừa nhận ra rằng nếu bạn đang sử dụng các đường dẫn đầy đủ, startswithnó sẽ không hoạt động, vì vậy bạn cần một regex
In [10]: a
Out[10]: ['/some/path/foo', 'some/path/bar', 'some/path/eph_thing']
In [11]: filter(lambda x: not re.search('/eph', x), a)
Out[11]: ['/some/path/foo', 'some/path/bar']
Làm thế nào về việc bỏ qua tệp cụ thể trong khi lặp lại tất cả các tệp trong thư mục! Đoạn mã dưới đây sẽ bỏ qua tất cả các tệp excel bắt đầu bằng 'eph'
import glob
import re
for file in glob.glob('*.xlsx'):
if re.match('eph.*\.xlsx',file):
continue
else:
#do your stuff here
print(file)
Bằng cách này, bạn có thể sử dụng các mẫu regex phức tạp hơn để bao gồm / loại trừ một tập hợp tệp cụ thể trong một thư mục.
globTôi khuyên bạn nên so sánh với pathlibbộ lọc một mẫu rất đơn giản.
from pathlib import Path
p = Path(YOUR_PATH)
filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]
và nếu bạn muốn lọc mẫu phức tạp hơn, bạn có thể xác định một hàm để làm điều đó, giống như:
def not_in_pattern(x):
return (not x.name.startswith("eph")) and not x.name.startswith("epi")
filtered = [x for x in p.glob("**/*") if not_in_pattern(x)]
sử dụng mã đó, bạn có thể lọc tất cả các tệp bắt đầu bằng ephhoặc bắt đầu bằng epi.
Nói chung, để loại trừ các tệp không tuân thủ một số shell regexp, bạn có thể sử dụng mô-đun fnmatch:
import fnmatch
file_list = glob('somepath')
for ind, ii in enumerate(file_list):
if not fnmatch.fnmatch(ii, 'bash_regexp_with_exclude'):
file_list.pop(ind)
Ở trên, đầu tiên sẽ tạo một danh sách từ một đường dẫn nhất định và tiếp theo sẽ xuất hiện các tệp không đáp ứng biểu thức chính quy với ràng buộc mong muốn.
Như đã đề cập trong câu trả lời được chấp nhận, bạn không thể loại trừ các mẫu có hình cầu, vì vậy sau đây là phương pháp để lọc kết quả toàn cầu của bạn.
Câu trả lời được chấp nhận có lẽ là cách tốt nhất để thực hiện công việc nhưng nếu bạn nghĩ rằng phần hiểu danh sách trông hơi xấu và muốn làm cho mã của bạn tối đa không có độ phức tạp (như tôi đã làm) thì bạn có thể làm điều này (nhưng lưu ý rằng điều này có thể kém hiệu quả hơn so với phương pháp hiểu danh sách):
import glob
data_files = glob.glob("path_to_files/*.fits")
light_files = np.setdiff1d( data_files, glob.glob("*BIAS*"))
light_files = np.setdiff1d(light_files, glob.glob("*FLAT*"))
(Trong trường hợp của tôi, tôi có một số khung hình ảnh, khung hình thiên vị và khung hình phẳng tất cả trong một thư mục và tôi chỉ muốn các khung hình ảnh)
Nếu vị trí của ký tự không quan trọng, chẳng hạn như để loại trừ tệp kê khai (bất cứ nơi nào tìm thấy _) với các phép toán globvà re- biểu thức chính quy , bạn có thể sử dụng:
import glob
import re
for file in glob.glob('*.txt'):
if re.match(r'.*\_.*', file):
continue
else:
print(file)
Hoặc theo một cách thanh lịch hơn - list comprehension
filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)]
for mach in filtered:
print(mach)
Bạn có thể sử dụng phương pháp dưới đây:
# Get all the files
allFiles = glob.glob("*")
# Files starting with eph
ephFiles = glob.glob("eph*")
# Files which doesnt start with eph
noephFiles = []
for file in allFiles:
if file not in ephFiles:
noephFiles.append(file)
# noepchFiles has all the file which doesnt start with eph.
Thank you.