2

Я написал скрипт для перечисления файлов на основе месяца, который читается пользователем, как показано ниже:-

echo "Enter Month"
read month
ls -al | awk '$6 == "$month" {print}'

И я даю пользовательский ввод как август, я не получаю никакого результата. Но когда я пишу

ls -al | awk '$6 == "Aug" {print}'

Я получаю точный результат. Я делаю что-то неправильно? Пожалуйста помоги

1 ответ1

8

Главное: имена переменных не раскрываются в одинарных кавычках. Это "лучшая" (то есть чуть менее неправильная) строка:

ls -al              | awk '$6 == "'"$month"'" {print}'
# this is in single quotes ^^^^^^^          ^^^^^^^^^

Но:

  1. Тем не менее, это может не получиться в некоторых регионах. Установите LC_ALL=C заранее или, может быть, так.
  2. С $month вы можете ввести (почти?) что-нибудь в awk . Есть лучшие способы использовать переменные в awk ; Опция -v должна быть намного безопаснее (спасибо user000001 за указание на это).
  3. Вы не должны анализировать вывод ls в первую очередь.

Правильное решение может использовать find и stat . Следующий код может быть не самым быстрым решением, но он более надежен из-за:

  • отбрасывая значения $month которые не соответствуют предопределенным,
  • используя find вместо парсинга ls .

Код:

#!/bin/sh
echo "Enter Month"
read month
case "$month" in
  1|01|Jan|jan|January|january)   monthN=01;;
  2|02|Feb|feb|February|february) monthN=02;;
# ...
  10|Oct|oct|October|october)     monthN=10;;
# ...
  *) echo Error! >&2; exit 1;;
esac
find ./ -maxdepth 1 -exec sh -c '[ `stat -c %y "$1" | cut -c 6-7` = "$2" ]' sh {} "$monthN" \; -ls

Я проверил это на Debian; это не может быть супер-портативный. Это показывает общий подход, хотя.

Последняя строка вызывает отдельную оболочку для каждого объекта в текущем каталоге (включая ./ себя). Эта оболочка использует stat для получения информации mtime, а затем cut из нее двухзначный номер месяца. [ ... ] сравнивает результат с выбранным номером месяца. Если этот тест пройден успешно, find выполняет собственный ls для объекта (вместо этого вы можете использовать -print или -print0 ).

Обратите внимание, что это никогда не возвращается ../ . С другой стороны, find позволяет использовать дополнительные тесты (например, -type f), поэтому этот подход очень гибок.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .