1

Я хочу написать скрипт, который будет принимать идентификатор в качестве ввода от пользователя. На основании этого ввода он будет искать каталоги, чтобы найти файл, который содержит данный идентификатор. Теперь в каталоге более 10 файлов, но все они имеют одинаковый идентификатор. Так что, если я использую grep он выдаст мне файлы только в отсортированном порядке. Я не хочу отображать все файлы, кроме самого последнего файла в каталоге, который содержит этот идентификатор. Предположим, у меня есть файлы a1 , a2 , a3 , a4 , a5 , a6 и т.д. Все файлы имеют некоторую информацию, но отличается только их идентификатор.

Я попробовал grep -lr "$read" | ls -ltr , но он отображает только файлы в порядке возрастания, не достигая полной цели. Я хочу подсказку / предложение, как бы я работал для рендеринга последнего файла с путем.

1 ответ1

0

Вот несколько подходов:

  • Если все файлы находятся в одном целевом каталоге ($dir), это тривиально:

    newest=$(ls -1tr $(grep -Hl "$read" "$dir") | tail -n 1)
    
  • Если вам также нужно перейти в подкаталоги:

    newest=$(ls -1tr $(find . -type f -exec grep -Hl "$read" {} \;) | tail -n 1)
    

Оба приведенных выше примера используют tail -n 1 для печати только последней строки отсортированного вывода ls . Тем не менее, разбор ls - очень плохая идея, и ее вообще следует избегать. Вот несколько более сложных, но более безопасных методов, которые могут работать с произвольными именами файлов:

  • Это использует несколько трюков, мне нужно использовать синтаксис { } для захвата переменной (см. Здесь). IFS= и -r гарантируют, что мы можем иметь дело со странными именами файлов, и stat чтобы получить время модификации файла. Самый новый файл сохраняется в переменной $newest .

    mdate=0; 
    fdate=0;
    newest=$(find . -type f -exec grep -Hl foo {} \; | 
    { 
        while IFS= read -r file; do 
            fdate=$(stat -c %Y "$file"); 
            if [ "$fdate" -gt "$mdate" ]; then 
                latest="$file"; 
                mdate="$fdate"; 
            fi; 
        done; 
        echo "$latest"; 
    })
    

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