2015-03-29 6 views
0

входного файла:получать последний открытый файл

wtf.txt|/Users/jaro/documents/inc/face/| 
lol.txt|/Users/jaro/documents/inc/linked/| 
lol.txt|/Users/jaro/documents/inc/twitter/| 
lol.txt|/Users/jaro/documents/inc/face/| 
wtf.txt|/Users/jaro/documents/inc/face/| 
omg.txt|/Users/jaro/documents/inc/twitter/| 
omg.txt|/Users/jaro/documents/inc/linked/| 
wtf.txt|/Users/jaro/documents/inc/linked/| 
lol.txt|/Users/jaro/documents/inc/twitter/| 
wtf.txt|/Users/jaro/documents/inc/linked/| 
lol.txt|/Users/jaro/documents/inc/face/| 
omg.txt|/Users/jaro/documents/inc/twitter/| 
omg.txt|/Users/jaro/documents/inc/face/| 
wtf.txt|/Users/jaro/documents/inc/face/| 
wtf.txt|/Users/jaro/documents/inc/twitter/| 
omg.txt|/Users/jaro/documents/inc/linked/| 
omg.txt|/Users/jaro/documents/inc/linked/| 

входной файл является список открытых файлов (открытие файла означает 1 строка файла) я хочу, чтобы получить последний открытый файл в

например : получить последний открытый файл в Dir/Users/Яро/документы/ИНК/лицо/

выход:

wtf.txt 
+1

Вы имеете в виду 'head -1 input_file.txt | cut -d \ | -f1'? Удачи. – shellter

+0

«Последний» как последняя строка в файле или файл с новейшей временной меткой изменения (временные метки доступа обычно отключены по очевидным причинам производительности) или что-то еще? – tripleee

+0

@tripleee i означает последний файл с заданной папкой (~/inc/face /). 14-я строка-'wtf.txt'..другие примеры: для папки ~/inc/twiiter/output является 'wtf.txt' - 15-я строка, для папки ~/inc/linked/это 'omg.txt' последняя строка в файле – DRINK

ответ

1

Это выбирает последнюю строку в файле, чье второе поле название нужной папки, и печатает первое поле.

awk -F '\|' '$2 == "/Users/jaro/documents/inc/face/" { f=$1 } 
    END { print f }' file 

Чтобы проверить, является ли самый последний файл также существующий файл, я хотел бы использовать оболочку, чтобы изменить порядок с tac и выполнить логику; пропустите файлы по неправильному пути, а те, которые не существуют, затем распечатайте первый успех и завершите работу.

tac file | 
while IFS='|' read -r basename path _; do 
    case $path in "/Users/jaro/documents/inc/face") ;; *) continue;; esac 
    test -e "$path/$basename" || continue 
    echo "$basename" 
    break 
done | 
grep . 

Окончательный grep . является производство код выхода, который отражает ли или нет команда успешно - если он напечатал файл, это нормально; если ни один из извлеченных файлов не существует, возвращайте ошибку.

Ниже мой первоначальный ответ, основанный на правдоподобной, но явно неправильной интерпретации вашего вопроса.

Вот краткая попытка найти файл с самым новым временем модификации из списка. Я избегаю parsing ls, предпочитая вместо этого использовать корректно обрабатываемый машиной вывод от stat. Поскольку ваш входной файл ориентирован на линию, я полагаю, что никакие имена файлов не содержат символы новой строки, что упрощает некоторые вещи.

awk -F '\|' '$2 == "/Users/jaro/documents/inc/face/" { print $2 $1 }' file | 
sort -u | 
xargs stat -f '%m %N' | 
sort -rn | 
awk -F '/' '{ print $NF; exit(0) }' 

Первый sort, чтобы удалить любые дубликаты, чтобы избежать запуска больше stat раза больше, чем необходимо (преждевременной оптимизации, возможно), то stat префиксы каждая строка со временем модификации файла, выраженной в секундах с начала эпохи, которая облегчает простая численная сортировка по возрасту, а окончательный сценарий Awk аккуратно объединяет head -n 1 | rev | cut -d/-f1 | rev, т. е. извлекает только базовое имя из первой строки вывода, а затем завершает работу.

Если есть какой-либо способ использовать менее сумасшедший формат ввода, это будет улучшение (возможно, и вашей жизни в целом).

Формат вывода из stat не правильно стандартизированы, но ваш вопрос помечается поэтому я предполагаю GNU CoreutilsBSDstat. Если требуется переносимость, возможно, посмотрите на find (который, однако, может быть чрезмерным и/или не намного лучше стандартизован на разных платформах) или вместо этого написал небольшой скрипт Perl или Python. (Ну, Руби тоже, я полагаю, но лично я бы пошел с Perl.)

perl -F'\|' -lane '{ $t{$F[0]} = (stat($F[1].$F[0]))[10] 
    if !defined $t{$F[0]} and $F[1] == "/Users/jaro/documents/inc/face/" } 
    END { print ((sort { $t{$a} <=> $t{$b} } keys %t)[-1]) }' file 
+0

спасибо за ваше решение, проблема в том, что у меня есть mac, и я не могу использовать что-либо вроде 'stat'. Я могу использовать только стандартные утилиты. – DRINK

+0

Тогда почему на ' Earth' это tagged [tag: linux]? – tripleee

+0

Обновлено для [tag: osx]; для справки, соответствующая команда 'stat' для Linux будет' stat -c '% y% f''. Но, основываясь на вашем комментарии выше, вы, очевидно, не заботитесь о временах изменения файлов, поэтому просто посмотрите на самое начало обновленного ответа. (И, пожалуйста, позаботьтесь о том, чтобы правильно определить свою проблему в следующий раз, когда у вас возникнет вопрос.) – tripleee

0

atime - The atime (время доступа) время, когда данные файла в последний раз. Отображение содержимого файла или выполнение сценария оболочки обновит файл atime. Вы можете просмотреть atime с ls -lu команды

http://www.techtrunch.com/linux/ctime-mtime-atime-linux-timestamps

Так что в вашем случае будет делать трюк.

ls -lu /Users/jaro/documents/inc/face/

+0

Зачем вам использовать' -ctime' вместо '-atime'? –

+0

@Suku вы можете разместить здесь полное решение? я не очень хорошо разбираюсь в bash ... – DRINK

+0

В этом разделе рассматриваются все файлы в каталоге, а не только те, которые перечислены во входном файле. – tripleee

Смежные вопросы