С оговоркой, что это решение не может обрабатывать такие вещи, как символ перевода строки в имени файла:
mkdir extract_images 2>/dev/null
while IFS= read -r file; do
mv "$file" extract_images
done < extract_images_list.txt
Он проходит через extract_images_list.txt построчно, считывая их в файл
(требуется аргумент -r
, чтобы он обрабатывал обратную косую черту как буквальную обратную косую черту, а IFS =
не убирает пробелы), затем перемещает каждую строку в каталог extract_images.
Вот решение с find
, которое также выводит имена файлов, содержащих совпадение:
find . -name "*.xml" -exec grep '<dbname>' {} \; \
-exec echo -e {}"\n" \; \
| sed 's/<dbname>\(.*\)<\/dbname>/\1/g'
Пояснение
find . -name "* .xml"
рекурсивно найти все XML-файлы из текущего каталога -exec grep '' {} \;
в каждом файле искать шаблон
-exec echo -e {} "\ n" \;
echo filename + новая строка ( -e
опция заставляет интерпретировать эхо \ n
) | sed 's / \ (. * \) <\ / dbname> / \ 1 / g'
выводит конвейер на sed
для печати только поля, содержащегося между
теги. ПРИМЕЧАНИЕ 1: вы можете отформатировать вывод в своем echo -e ...
, чтобы результаты для каждого файла были четко представлены, например добавляя новые строки или строки подчеркивания, в зависимости от того, что вам нужно.
ПРИМЕЧАНИЕ2: путь к каждому файлу будет указан относительно .
(например, ./ subfolder1 / file.xml
).Если вам нужен абсолютный путь, введите найдите $ PWD -name ...
.
Использование правильного синтаксического анализатора XML для синтаксического анализа XML:
shopt -s globstar nullglob
for file in **/*.xml; do
dbname=$(xmlstarlet sel -t -v '//dbname' "$file")
[[ -n "$dbname" ]] && printf "%s\t%s\n" "$file" "$dbname"
done
Предположим, у нас есть каталог XMLS
, содержащий эти файлы:
cat XMLS/file1
foo bar <dbname>target</dbname> baz
foo foo
cat XMLS/file2
<name>notarget</name>
Я бы использовал эту команду:
grep -r '<dbname>' XMLS/ | sed 's/.*<dbname>\(.*\)<\/dbname>.*/\1/'
target
Как видите, она возвращает значение внутри
теги. А не значение внутри тегов
.
Флаг -r
для grep
выполняет рекурсивный поиск.
sed
удаляет из строки все, кроме значения target
.
Использование find
сxq
:
find testmag -type f -name '*.xml' -exec xq -r '..|(.dbname? // empty)' {} +
Это позволит найти все обычные файлы с именами, соответствующими *.xml
, в каталоге testmag
или ниже него. Для их пакетов будет вызываться xq
для извлечения значения каждого узла dbname
, найденного в этих документах.
xq
— это анализатор XML, подобный jq
-, который распространяется вместе с yq
из https://kislyuk.github.io/yq/
Если вам нужны имена всех XML-файлов, содержащих этот узел, вы можете использовать
find testmag -type f -name '*.xml' -exec xq -e '..|(.dbname? // empty)' {} \; -print
... хотя это будет немного медленнее, чем просто извлечение значения узла, поскольку нам нужно вызывать xq
один раз для каждого файла.