Как узнать, какие файлы были изменены командой "ed"?

Если вы можете использовать jq, Librivox API также предоставляет выходные данные JSON, и, возможно, будет проще анализировать JSON с помощью jq, чем XML с помощью соответствующих инструментов XML.

u='https://librivox.org/api/feed/audiobooks/?offset=0&limit=3&fields=%7Blanguage,authors,title,url_zip_file%7B&format=json'
curl "$u" -sL |
  jq -r '.books[] | "\(.language).\(.authors[0].last_name +.authors[0].first_name).\(.title).zip",.url_zip_file'

Дает вывод, подобный:

English.DumasAlexandre.Count of Monte Cristo.zip
http://www.archive.org/download/count_monte_cristo_0711_librivox/count_monte_cristo_0711_librivox_64kb_mp3.zip
English.BalzacHonoré de.Letters of Two Brides.zip
http://www.archive.org/download/letters_brides_0709_librivox/letters_brides_0709_librivox_64kb_mp3.zip
English.DickensCharles.Bleak House.zip
http://www.archive.org/download/bleak_house_cl_librivox/bleak_house_cl_librivox_64kb_mp3.zip

После этого использовать его относительно простоxargs:

curl "$u" -sL |
  jq -r '.books[] | "\(.language).\(.authors[0].last_name +.authors[0].first_name).\(.title).zip",.url_zip_file' |
  xargs -d '\n' -n2 wget -O

Где xargsиспользует две строки в качестве аргумента для wget, причем первая строка становится параметром опции -O, а вторая — URL-адресом.

Хотя я бы порекомендовал решение на основе Python -, подобное предложенному Джейми , за исключением использования JSON и встроенных в Python возможностей JSON вместо bs4.

1
19.03.2020, 23:41
1 ответ

Ваша команда немного неверна, так как <<<является перенаправлением ввода (здесь -строка ), которая прикреплена к find, а не к ed.

Чтобы немного расширить вашу команду:

find. -type f -exec sh -c '
    for pathname do
        echo w | ed -s "$pathname"
    done' sh {} +

Это повлияет только на обычные файлы в текущем каталоге или где-нибудь под ним, и не будет пытаться редактировать каталоги и другие типы файлов с помощью ed. Обратите внимание, что двоичные файлы также являются обычными файлами, поэтому мы должны предположить, что вы запускаете это только в каталогах, содержащих текстовые файлы (, чтобы не повредить скомпилированные исполняемые файлы, файлы изображений и т. д.)

Для пакетов обычных файлов это вызовет короткий -строковый сценарий оболочки. Сценарий зацикливался на путях, данных ему find, и открывал каждый в edтолько для немедленного сохранения файла. Это добавляет новую строку к файлам, которые еще не заканчиваются символом новой строки.

Чтобы получить подсказку о том, какие файлы на самом деле изменены, распечатайте путь перед вызовом ed. Это выведет все найденные имена путей, но список будет перемежаться сообщениями «Добавлена ​​новая строка» после некоторых из них.

find. -type f -exec sh -c '
    for pathname do
        printf "%s\n" "$pathname"
        echo w | ed -s "$pathname"
    done' sh {} +

Чтобы определить, какие файлы были фактически изменены, вы можете записать во временный файл, сравнить его с исходным файлом и заменить исходный временным файлом, если есть разница.

find. -type f -exec sh -c '
    tmpfile=$(mktemp); trap "rm -f \"$tmpfile\"" EXIT
    for pathname do
        printf "w %s\n" "$tmpfile" | ed -s "$pathname" 2>/dev/null
        if ! cmp -s "$tmpfile" "$pathname"; then
            printf "Fixed %s\n" "$pathname"
            mv "$tmpfile" "$pathname"
        fi
    done' sh {} +

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

Это также подавляет сообщение «Добавлена ​​новая строка» из edи вместо этого выводит пользовательское сообщение всякий раз, когда файл фактически был изменен.

См. также:

1
28.04.2021, 23:20

Теги

Похожие вопросы