GNU параллельно удалить escape перед пробелами в команде

824
Carambakaracho

В настоящее время я тестирую GNU параллельно, чтобы распределить команду сравнения по нескольким серверам, используя bash. В своей основной функции эта команда сравнения принимает два входа для сравнения (доступ к базе данных Oracle) и требует имя выходного файла через -o. Программа требует как минимум одно действие загрузки, сохранения или прямой загрузки.

compare -o cmp.input1.input2.dat Input1 Input2 

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

#test_parallel -o cmp.input1.input2.dat Input1 Input2 -o cmp.input1.input3.dat Input1 Input3 -o cmp.input2.input3.dat Input2 Input3 [...] 

и выполнить команду с использованием параллельного интерфейса, однако выполнить команду сравнения не удалось

parallel -a test_parallel "compare {}" ERROR: No action specified for results (load, save or direct upload) usage: compare [-u][-o <file>] query target 

используя --dryrunрежим это то, что параллельно выполняет:

compare -o\ cmp.input1.input2.dat\ Input1\ Input2 

По какой-то причине я не понимаю, пробел не обрабатывается корректно программой сравнения. Выполнение этой команды в bash приводит к точно так же сообщению об ошибке. Удаление экранирования после флага -o (я мог бы переместить -o в параллельную команду) приводит к ошибке «слишком много аргументов». Удаление всех escape-кодов запускает команду, как и ожидалось.

Можно ли сказать параллель не печатать escape при вызове команды? Я не вижу ничего в документации, кроме того, что это ожидаемое поведение по умолчанию, как указаноparallel --shellquote

1

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

2
Ole Tange

GNU Parallel обрабатывает ввод как один аргумент и заключает его в кавычки, чтобы вы могли безопасно использовать такие имена файлов, как:

My brother's 12" records costs 30$ each.txt 

В вашем случае вы хотите, чтобы аргумент был проанализирован оболочкой, поэтому пробелы не будут заключены в кавычки:

parallel -a test_parallel eval compare {} 

Или вы можете разделить на пространство:

parallel --colsep ' ' -a test_parallel compare 

Но так как вы хотите сравнить все со всеми, вы можете сделать это более элегантно:

parallel cmp -o ../out/cmp.. ::: Input* ::: Input* 

Это позволит сравнить все входные данные * со всеми входными данными *. С помощью --resultsвы можете получить хорошо структурированные результаты в директории:

parallel --results out/ cmp ::: Input* ::: Input* 

Но если вы хотите пропустить запуск cmp InputY InputXпосле того, как уже пробежали, cmd InputX InputYто вы можете сделать это:

parallel --results out/ cmp {=1' $arg[1] ge $arg[2] and $job->skip();' =} ::: Input* ::: Input* 
Спасибо, Оле, комбинация с `eval` как раз то, что мне было нужно. Разделение по пространству, вероятно, не будет работать, потому что количество аргументов изменяется в зависимости от ввода. Программа сравнения, которую я использую, выполняет сравнение биологических последовательностей и сообщает о наиболее близких совпадениях, что является особым случаем Carambakaracho 8 лет назад 0

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