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

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

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}' 

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

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; }' 
  • Написание сценария оболочки Unix для вызова функции C и перенаправления данных в файл .txt
  • Как я могу заставить pwd разрешить мягкую ссылку?
  • Как grep блок xml в XML-файле с использованием ключевого слова в ksh
  • Как читать и делать min / max / avg из потока NMEA
  • Интерактивное удаление файлов из списка
  • Можно ли удалить все права на запись в оболочке для текущего пользователя
  • Разделение столбцов и представление значения как stdin в отдельную программу в скрипте
  • Пара арифметических связанных команд, Dash, POSIX shell, sh, Increment
  • Добавление backtick (`) в вывод heredoc в команде оболочки
  • Как создать постоянную переменную
  • Заменить колонку с результатом команды
  • Как удалить повторяющиеся строки из файла?
  • Linux и Unix - лучшая ОС в мире.