Рекурсивный список символических ссылок на заданную папку с их полным путем

Я хотел бы просмотреть свою домашнюю папку и перечислить все символические ссылки, которые указывают на элемент, имеющий Dropbox на своем пути. Следующая команда (плюс некоторая постобработка для удаления дополнительного поля информации, но это не должно быть сложным) почти выполняет задачу.

ls -alR ~ | grep -e "->" | grep Dropbox

В выводе моего ls маркер -> предшествует пути к цели символической ссылки. Чтобы получить только символические ссылки, указывающие на что-то в Dropbox, я передаю вывод через окончательный grep. Однако есть проблема: таким образом я получаю только имя символической ссылки, а не полный путь. С другой стороны, используя команду типа:

ls -alR ~ | grep -e "->" | grep -E '(Dropbox|:)'

сохранение списка путей ls (в рекурсивном поиске ls сначала выводит указанную папку, за которой следует двоеточие) приводит к слишком большому количеству совпадений. Любые идеи?


person GFR    schedule 30.11.2013    source источник
comment
Остерегайтесь трудностей анализа вывода ls, если вам приходится иметь дело с враждебными именами файлов (содержащими, например, -> или новую строку, а иногда даже пробелы и табуляции).   -  person Jonathan Leffler    schedule 30.11.2013
comment
Да, именно поэтому вы всегда должны использовать настоящий язык программирования (то есть не сценарии оболочки) для написания программного обеспечения для бизнеса. Но для быстрого личного сценария это, вероятно, нормально.   -  person Robin Green    schedule 30.11.2013
comment
Правильно, не должно быть слишком враждебных файлов, это для личного пользования. Как выделить часть кода в сообщении? Я видел, что вы сделали это для меня, спасибо!   -  person GFR    schedule 30.11.2013
comment
Подсветка кода — отступ на (минимум) 4 пробела. Чтобы сделать это быстро, выберите код, для которого нужно сделать отступ, затем нажмите кнопку {} над полем редактирования. (Ходят слухи, что это делает и комбинация control-K; я ей не пользовался.)   -  person Jonathan Leffler    schedule 30.11.2013
comment
Если вы хотите увидеть враждебные файлы, попробуйте запустить этот скрипт (в мусорном каталоге, а не в каталоге с ценными данными): ls -la | while read -r line1 && read -r line2; do cp /dev/null $'\n'"$line1"$'\n'"$line2"; done. Это работает «лучше», если у вас есть символические ссылки в каталоге. Это в значительной степени гарантирует, что наивные сценарии оболочки потерпят ужасный сбой.   -  person Jonathan Leffler    schedule 30.11.2013
comment
@JonathanLeffier Итак, хотя мы нашли ответ на мой вопрос, я понял, что из-за пробелов в именах файлов извлечение правильных полей с помощью awk и их обработка для получения красивой и чистой исходной цели ln -s гораздо сложнее. чем должно быть. Поэтому мне было интересно: это путь или я должен использовать другой язык? При случае что посоветуете?   -  person GFR    schedule 30.11.2013
comment
Вы можете создавать очень надежное программное обеспечение на Python, что я бы рекомендовал в этом случае.   -  person uselpa    schedule 18.01.2014


Ответы (1)


person    schedule
comment
Я предлагаю добавить -d к параметрам ls, чтобы, если символическая ссылка указывала на каталог, вы не получали список каталогов. Вы также можете рассмотреть find ~ -type l -exec ls -ld {} + | grep Dropbox. - person Jonathan Leffler; 30.11.2013
comment
@JonathanLeffler спасибо, забыл об опции -d - я включил ее в свой ответ. - person Robin Green; 30.11.2013
comment
Спасибо, Робин. Почти так, но в нем также перечислены файлы, у которых Dropbox указан в пути ссылки, а не в цели. Я попытался изменить grep Dropbox на grep -E '.*-›.*Dropbox', но это не работает - я не знаю, почему. Поигравшись, я обнаружил, что ls -l $(find ~ -type l) 2› /dev/null | grep -E '.*-›.*Dropbox' › ~/Desktop/output.txt работает, даже если он не очень чистый: ls жалуется на то, что некоторые вещи не существуют, поэтому я отправил stderror в /dev/null - person GFR; 30.11.2013
comment
На самом деле мое решение действительно не работает с именами файлов, содержащими пробелы. Ответ Джонатана с изменением, которое я предложил в последнем grep, кажется мне наиболее подходящим: find ~ -type l -exec ls -ld {} + | grep Дропбокс. - person GFR; 30.11.2013
comment
Хорошо, это была командная работа! :) - person Robin Green; 30.11.2013