Получить файлы с именем, содержащим значение даты, меньшее или равное заданной дате ввода

Одна из моих папок содержит файлы в следующем формате:

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 

Я хочу получить те файлы, у которых значение даты меньше или равно моему значению даты ввода.

Например, если я даю «3_20150414», то есть (3_YYYYMMDD), я хочу, чтобы на выходе были имена файлов

 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 

Я могу перечислить файлы, выпустив команду следующим образом:

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

Но я пытаюсь найти <= матч.

  • Существует ли простой способ ограничения числа дочерних процессов, выполняемых параллельно?
  • Удалите файлы, которые предоставляются по каналу
  • Как проверить, какая строка скрипта bash выполняется
  • извлеките файл из jar-файла и получите diff
  • Есть что-то вроде «split ()» JavaScript в оболочке?
  • Печать состояния файлов, обрабатываемых при использовании find
  • Найдите полный путь и имя файла под каталогом, затем перейдите в исполняемый файл в качестве аргументов
  • Loop до тех пор, пока grep не найдет текст в файле
  • 3 Solutions collect form web for “Получить файлы с именем, содержащим значение даты, меньшее или равное заданной дате ввода”

    Вы можете использовать awk и его оператор сравнения строк.

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

    В переменной:

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

    конкатенирование с помощью «z» здесь гарантирует, что сравнение представляет собой сравнение строк и позволяет в любое время в этот день, так как в локали C цифры сортируются до z .

    grep не имеет оператора ≤ как такового , но есть способ его подделать. Вы хотите, чтобы все даты между годом 0 (или годом 1, в зависимости от того, какой был первый год) до 20150414. (Я буду считать, что даты BC не указаны за столом.) Разделите этот диапазон на поддиапазоны, которые могут быть сопоставлены регулярными выражениями:

    • Год от 0 до 1999 года – все годы начинаются с 0 или 1, поэтому grep для [01] .
      (Все регулярные выражения будут считаться привязаны в начале строки сразу после «3_».)
    • 2000 – 2009 гг. – регулярное выражение 200 .
    • Год 2010 по 2014 год – регулярное выражение 201[0-4] .
    • Год 2015, месяц 1 – месяц 3 – 20150[1-3] .
    • Год 2015, месяц 4, день 1 – 9 – 2014040
    • Год 2015, 4 месяц, день 10-14 – 2014041[0-4]

    а затем собрать их все вместе:

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

    ls -l , конечно, дает вам много информации о файлах (режиме, владельце, времени работы и т. д.), которые вам не нужны, поэтому вы используете awk '{print $NF}' чтобы разбить его и оставить только имя файла. Это неэффективно и подвержено ошибкам (он ломается, если в имени файла есть пробел или вкладка). Анализ вывода из ls никогда не является отличной идеей, но вы можете сделать его немного более безопасным, сделав его немного проще: просто не получайте информацию, которую вы не хотите или не хотите, и тогда вам не нужно отбрасывать Это.

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

    должно быть достаточно хорошим.

    Но создание этого шестичастного регулярного выражения является утомительным и подверженным ошибкам, и сложным (хотя и не невозможным) сценарием. Вот более чистый способ:

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

    Это извлекает восемь символов, начиная с 3-й позиции (т. Е. После «3_») и сравнивает ее с 20150414 как два восьмизначных числа.

    Возможное решение с использованием вашего примера:

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

    Я немного изменил ваш шаблон grep и передал искомое значение в качестве аргумента awk где мы просто сравниваем строки для вывода желаемых вещей.
    Также есть много статей, почему вы не должны разбирать ls поэтому я немного меняю его с помощью find:

     find . -type f -name '*3_2015*' -printf "%f\n" | awk -vd='3_20150414' '{ s = substr($NF, 1, 10); if (length(s) == 10 && s <= d) print $NF; }' 
    Interesting Posts

    скрипт для подсчета файлов в каталоге

    Как проверить программно, если кабель Ethernet подключен?

    Прочитайте другую память процессов, используя ptrace () в C / CPP

    Отсутствие Fedora в grub после установки Ubuntu

    Обнаружение трафика интерфейса с IP-адресом

    Как извлечь цвета из PDF-файла?

    Как просмотреть все необработанное сообщение в альпийском?

    Может ли Awk читать экранированные строки? Т.е. читать прошлые строки

    Установка сервера SME с USB-сбоев с «IOError: Файловая система только для чтения"

    Видя гораздо меньше полезного пространства, чем ожидалось, с помощью нового тома с использованием ZFS на Centos 7

    Как связать разные (несовместимые) библиотеки во время выполнения в зависимости от программы?

    У моего Ubuntu есть модуль для USB 2.0?

    Как восстановить базу данных Mysql в Linux?

    Некоторые функции кальмара не работают, иногда вообще ничего не работают

    Как проверить, определена ли переменная вообще в Bash до версии 4.2 с помощью опции оболочки nounset?

    Linux и Unix - лучшая ОС в мире.