Найдите файлы, содержащие строку, и переместите соответствующий файл в другой каталог

Использование XMLStarlet(иногда устанавливается как xmlstarlet, а неxml):

paths=( $( xml sel -t -v '//FileSetFolder/Path' file.xml ) )

for path in "${paths[@]}"; do
    filetypes=( $( xml sel -t -v "//FileSetFolder[Path=\"$path\"]/FileType" file.xml ) )

    for filetype in "${filetypes[@]}"; do
            printf 'Path "%s" has a filetype "%s"\n' "$path" "$filetype"
    done
done

Выход:

Path "D:\apache-2.4.10\htdocs" has a filetype "rep"
Path "D:\apache-2.4.10\htdocs" has a filetype "zip"
Path "D:\apache-2.4.10\htdocs" has a filetype "mnt"
Path "D:\Download\ROSXcenterAutoArchive\ArchiveStorage\archive" has a filetype "mnt"
Path "D:\Download\ROSXcenterAutoArchive\ArchiveStorage\archive" has a filetype "952230"

-1
07.04.2020, 16:04
2 ответа

У меня есть для вас 3 варианта, Основные идеи:

  1. grep | xargs mv
  2. grep | parallel mv
  3. find -exec grep -q -exec mv

1.grep | xargs mv

Используйте grepи xargs:

.
grep -FlZ "some string" *.txt \
| xargs -0 -I{} sh -c 'echo mv "$1" "${1%.*}.pdf" some/other/directory' xargs-sh {}

grep:

  • -Fсоответствует полной строке, а не шаблону
  • -lвыводить только совпадающие имена файлов
  • -Zнулевой вывод -разделитель между именами файлов (Это важно, потому что имена файлов могут иметь символы новой строки, поэтому вы не можете полагаться на новую строку в качестве разделителя)

xargs:

  • -0считывает ноль -данные с разделителями

2.grep | parallel mv

С помощью xargsвам нужно вызвать подоболочку, используя sh -c, чтобы иметь возможность получить соответствующее имя файла PDF.

Вместо этого вы также можете использовать GNU parallelклассные функции !!

grep -FlZ "some string" *.txt \
| parallel -0 -j1 echo mv {} {.}.pdf some/other/directory
  • -j1только одно задание за раз
  • {}имя файла
  • {.}имя файла без расширения

3.find -exec grep -q -exec mv

И еще один вариант, использующийfind:

find. -maxdepth 1 -name "*.txt" \
-exec grep -Fq "some string" {} \; \
-exec sh -c 'echo mv "$1" "${1%.*}.pdf" some/other/location' find-sh {} \;
  • -maxdepth 1чтобы не повторять
  • grep -q, чтобы просто получить код ошибки вместо имен файлов, второй -execзапустится только после успешного завершения первого.
  • Второй -execв основном аналогичен xargsв первом варианте.
  • нам не нужно делать ничего -с разделителями вывода, потому что мы не передаем никаких имен файлов, findпозаботится об этом.

Для каждого параметра удалите echo, если результат вас устраивает.

4
28.04.2021, 23:18

Если у вас нет команды parallel, сделайте с двумя xargs, как показано ниже

grep -l 'search string' *.txt | xargs -I {} basename {}.txt | xargs -I {} cp {}.pdf /destination-directory
1
28.04.2021, 23:18

Теги

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