Как вывести список всех подкаталогов, содержащих файл - PullRequest
1 голос
/ 14 апреля 2011

Мне нужно выполнить следующую задачу:

Для заданного списка имен файлов и для заданного каталога выведите для каждого имени файла все подкаталоги, в которых оно появляется.Подкаталоги будут напечатаны в порядке убывания на основе даты создания файла.

Я не знаю, как это сделать

Ответы [ 5 ]

1 голос
/ 14 апреля 2011
for file in $(< filelist) 
do 
    find -name "$file" -printf "%C@ %h\n" | sort -rn | sed 's/^[0-9.]* //'
done 
  • $ (
  • printf% C @ печатает время в секундах с 1.1.1970
  • % h печатает ведущие каталоги без имени файла
  • sort -n сортирует числа, -r в обратном порядке
  • sed удаляет время после сортировки

Проблемы:

  • Исходя из вопроса, нет указания на печать самого имени файла, что необычно для сценария реального мира.Это будет легко решено.
  • Плохо обрабатываются имена путей с переносами строк, а также другие причудливые символы, такие как вертикальная табуляция, подача формы и т. Д.
1 голос
/ 14 апреля 2011

Поскольку придумывать личное любимое решение - это весело, я присоединюсь:

Решение (Спойлер)

@ пользователь неизвестен:

Я знаю, что вы троллинг, но в интересах случайных читателей Я допускаю, что встроенные расширения там небезопасны. Я действительно показывал, как я собирался использовать команды (ls, find, uniq) и т. Д. В комбинации. Это можно сделать безопасным:

find -type f -printf '%f\0' | sort -uz |
    xargs -0i -n1 find -name {} -printf "%f:%p\n"

Форматирование теперь немного менее удобно (опять же, как вы бы отформатировали его с помощью специальных символов в путевых именах?). Вопрос мало говорит на эту тему, так что ...


Последнее замечание:

the first read is already broken with (...) blanks in filenames

  • неверно while read только с символами новой строки, попробуйте: read line <<< "a b c" && echo "'$line'"

Оригинальные дидактические указатели

Используйте

dirname
     a/b/c/file -> a/b/c
basename
     a/b/c/file -> file
ls -t / ls -tr
     sort files by timestamp; note that 'creation date' is likely a fob because hardly any filesystem stores these reliably (it is usually the last change date for the inode)

find -type f
find -type d
     find files or directories
sort | uniq
sort -u
     sort lines and remove adjacent (subsequent) duplicates

Дайте мне знать, помогло ли это. Я мог бы сделать небольшой шаг, кроме указателей на команды UNIX

0 голосов
/ 14 апреля 2011

Работает только под Linux, но это было в ОП:

#!/bin/sh

for file in fileNameA fileNameB; do
  echo "File ${file} is in the following directories:"
  find sourceDir -type f -name ${file} -printf "%T@\t%h\n"|sort -rn|cut -f2
done

Подсказка: Если вы пропустите часть cut -f2, вы также увидите время создания (последнего изменения) для файлов.

0 голосов
/ 14 апреля 2011

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

#!/bin/sh

F=$(mktemp)
trap "rm -f $F" 0
find ${1?Usage: $(basename $0) path [file...]} > $F
shift
while test $# -gt 0; do
  grep $1 $F
  shift
done

Одна приятная особенность этого скрипта в том, что он запускается только один раз. Чтобы выполнить сортировку, одним из хороших методов было бы напечатать статистику, по которой вы хотите выполнить сортировку, в временный файл, а затем просто передать выходные данные цикла while для сортировки. Как отмечено в комментарии, grep не особенно надежен, поскольку он может соответствовать путям, которые не являются точными совпадениями.

0 голосов
/ 14 апреля 2011

Вы можете использовать комбинацию for (для циклического перебора ваших файлов) и find для поиска ваших файлов.

cat > filenames <<EOF
file-a
file-b
file-c
EOF

export DIR=dir-d

for filename in `cat filenames`; do find $DIR -name $filename ; done

Проверьте страницу справки 'find', чтобы узнать, что еще вы можете сделать; Вы можете легко запускать другие команды (с -exec).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...