Nhận tệp có tên chứa giá trị ngày nhỏ hơn hoặc bằng ngày nhập cụ thể


7

Một trong những thư mục của tôi chứa các tệp theo định dạng sau:

3_20150412104422154033.txt
3_2015041211022775012.txt
3_20150412160410171639.txt
3_20150412160815638933.txt
3_20150413161046573097.txt
3_20150413161818852312.txt
3_20150413163054600311.txt
3_20150413163514489159.txt
3_2015041321292659391.txt
3_20150414124528747462.txt
3_20150414125110440425.txt
3_20150414134437706174.txt
3_20150415085045179056.txt
3_20150415100637970281.txt
3_20150415101749513872.txt

Tôi muốn truy xuất các tệp có giá trị ngày nhỏ hơn hoặc bằng giá trị ngày đầu vào của mình.

Ví dụ: nếu tôi đưa ra "3_20150414" là (3_YYYYMMDD), tôi muốn đầu ra là tên tệp

3_20150412104422154033.txt
3_2015041211022775012.txt
3_20150412160410171639.txt
3_20150412160815638933.txt
3_20150413161046573097.txt
3_20150413161818852312.txt
3_20150413163054600311.txt
3_20150413163514489159.txt
3_2015041321292659391.txt
3_20150414124528747462.txt
3_20150414125110440425.txt
3_20150414134437706174.txt

Tôi có thể liệt kê các tệp bằng cách phát lệnh như thế này:

ls -l | grep '20150413\|20150414' |awk '{print $NF}'

Nhưng tôi đang vật lộn để tìm một <=trận đấu.


1
+1 để sử dụng định dạng YYYYMMDD, cho phép các chuỗi ngày được coi là số (và để so sánh chính xác).
G-Man nói 'Phục hồi Monica'

Câu trả lời:


6

Bạn có thể sử dụng awkvà toán tử so sánh chuỗi của nó.

ls | awk '$0 < "3_20150415"'

Trong một biến:

max=3_20150414 export max
ls | LC_ALL=C awk '$0 <= ENVIRON["max"] "z"'

nối với "z" ở đây đảm bảo rằng phép so sánh là so sánh chuỗi và cho phép bất kỳ lúc nào trong ngày đó kể từ Cmiền địa phương, các chữ số sắp xếp trước đó z.


2

grepkhông có toán tử per mỗi se , nhưng có một cách giả để làm giả nó. Bạn muốn tất cả các ngày trong khoảng từ năm 0 (hoặc năm 1; bất kể năm đầu tiên) đến 20150414. (Tôi sẽ giả sử rằng các ngày BC không có trong bảng.) Chia phạm vi này thành các phần phụ có thể khớp với các biểu thức thông thường:

  • Năm 0 đến 1999 - tất cả các năm bắt đầu bằng 0 hoặc 1, vì vậy grep cho [01].
    (Tất cả các biểu thức chính quy sẽ được giả định là được neo ở đầu dòng, ngay sau Lời 3_.
  • Năm 2000 đến 2009 - regex 200.
  • Năm 2010 đến 2014 - regex 201[0-4].
  • Năm 2015, tháng 1 đến tháng 3 - 20150[1-3].
  • Năm 2015, tháng 4, ngày 1 đến 9 - 2014040
  • Năm 2015, tháng 4, ngày 10 đến 14 - 2014041[0-4]

và sau đó đặt tất cả chúng lại với nhau:

grep -E '3_([01]|200|201[0-4]|20150[1-3]|2015040|2015041[0-4])'

ls -l, tất nhiên, cung cấp cho bạn nhiều thông tin về các tệp (chế độ, chủ sở hữu, thời gian mod, v.v.) mà bạn không cần, vì vậy bạn sử dụng awk '{print $NF}'để loại bỏ nó và chỉ để lại tên tệp. Điều này là không hiệu quả và dễ bị lỗi (nó bị hỏng nếu tên tệp có khoảng trắng hoặc tab trong đó). Phân tích đầu ra từ lskhông bao giờ là một ý tưởng tuyệt vời, nhưng bạn có thể làm cho nó an toàn hơn một chút bằng cách làm cho nó đơn giản hơn một chút: chỉ cần không nhận được thông tin bạn không muốn hoặc cần, và sau đó bạn không cần phải loại bỏ nó .

ls | grep -E '3_([01]|200|201[0-4]|20150[1-3]|2015040|2015041[0-4])'

nên đủ tốt

Nhưng việc xây dựng biểu thức chính quy sáu phần đó là tẻ nhạt và dễ bị lỗi, và khó (mặc dù không phải là không thể) đối với kịch bản. Đây là một cách sạch hơn:

ls | awk 'substr($1, 3, 8) <= 20150414'

Điều này trích xuất tám ký tự bắt đầu bằng vị trí thứ 3 (nghĩa là, sau Số 3_và) và so sánh nó với 20150414 là hai số có tám chữ số.


1

Giải pháp có thể sử dụng ví dụ của bạn:

ls -l | grep '3_2015' | awk -v d='3_20150414' '{ s = substr($NF, 1, 10); if (length(s) == 10 && s <= d) print $NF; }'

Tôi đã thay đổi một chút mẫu grep của bạn và chuyển giá trị tìm kiếm thành đối số để awkchúng ta chỉ so sánh các chuỗi với đầu ra những điều mong muốn.
Ngoài ra có rất nhiều bài viết tại sao bạn không nên phân tích cú phápls vì vậy tôi thay đổi nó một chút với find:

find . -type f -name '*3_2015*' -printf "%f\n" | awk -v d='3_20150414' '{ s = substr($NF, 1, 10); if (length(s) == 10 && s <= d) print $NF; }'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.