Как получить номер строки в xargs?

330
Poma

Я хочу загружать некоторые файлы на машины параллельно. Есть список хостов и список файлов, которые должны быть загружены по индексу: 1.txtидет hostOne, 2.txtидет и hostTwoт. Д. Вот что я пытаюсь сделать:

cat hosts | xargs -P 10 -I {} scp ./$.txt user@{}:/tmp 

Как заставить это работать ( $не входит в синтаксис xargs)?

0

2 ответа на вопрос

2
Attie

xargsне могу интерпретировать номера строк для вас. Вместо этого вы должны использовать что-то вроде nlдобавления строк:

$ echo -ne "a\nb\nc\n" \ | nl -bt -nln 1 a 2 b 3 c 

Затем вам нужно отформатировать команду, чтобы ее можно было передавать в xargsкачестве аргументов scp, используя что-то вроде sed:

$ echo -ne "a\nb\nc\n" \ | nl -bt -nln \ | sed -re 's!^([0-9]+) +\t(.+)$!./\1.txt user@\2:/tmp!' ./1.txt user@a:/tmp ./2.txt user@b:/tmp ./3.txt user@c:/tmp 

Наконец-то беги!

$ echo -ne "a\nb\nc\n" \ | nl -bt -nln \ | sed -re 's!^([0-9]+) +\t(.+)$!./\1.txt user@\2:/tmp!' \ | xargs -P10 -l1 -t scp scp ./1.txt user@a:/tmp scp ./2.txt user@b:/tmp scp ./3.txt user@c:/tmp 

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

nl

  • -bt - число только непустых строк
  • -nln - использовать выравнивание по левому краю без начальных нулей

sed

  • -r - использовать расширенное регулярное выражение
  • -e 's!^([0-9]+) +\t(.+)$!./\1.txt user@\2:/tmp!' - скрипт для использования
    • ^([0-9]+) +\t(.+)$совпадение чисел с последующими пробелами, затем табуляцией, затем любым символом
    • \1.txt user@\2:/tmp- замены, используя группы выше (внутри ())

xargs

  • -P10 - запускать до 10 процессов одновременно
  • -l1- ограничить xargsиспользование одной строки ввода на процесс
  • -t - печатать команды по мере их выполнения
@ хорошее объяснение! В сочетании с подсказкой `awk` ниже это выглядит довольно просто Poma 5 лет назад 0
@Poma Официальное примечание: в общем, нет "ниже". Порядок ответов не фиксирован. У вас есть три варианта чуть выше всех ответов, чтобы изменить их порядок для себя. Kamil Maciorowski 5 лет назад 0
2
Kamil Maciorowski

Этот фильтр

awk '' 

превращается fooв 1.txt user@foo:/tmp. Число увеличивается с каждой строкой. Ваша команда должна быть такой:

<hosts awk '' | xargs -L 1 scp 

Настройте его в соответствии с вашими потребностями (например -P 10). Также обратите внимание, что вам не нужно catчитать файл.