Как использовать ProcessBuilder с bash -c, если команда имеет двойные кавычки

Мне нужно соединить два огромных файла на основе нескольких столбцов. Символ вертикальной черты (|) является разделителем в обоих файлах.

Прямо сейчас я генерирую команду соединения unix, записываю ее в сценарий оболочки, а затем выполняю сценарий оболочки с помощью ProcessBuilder для получения желаемого результата.

Команда выглядит примерно так:

join -a 1 -a 2 -t \| -1 1 -2 1 -o 1.3,1.4,1.5,1.6,1.7,2.3,2.4,2.5,2.6,2.7 <(<"/home/input file 1" awk -F'|' 'NR>1{print $3"~&~"$4"|"$0}' | sort -k1 -t\| ) <(<"/home/input file 2" awk -F'|' 'NR>1{print $3~&~$4"|"$0}' | sort -k1 -t\| ) > "/home/output file"

Это работает, как ожидалось.

Я пытаюсь пропустить этап записи команды в сценарий оболочки с помощью bash -c. Но я сталкиваюсь с проблемами в основном из-за двойных кавычек (") и доллара ($) в команде awk. Я пытался избежать их, используя обратную косую черту, но это было бесполезно.

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

long pid = -1;
try {
    StringBuilder completeCommand = new StringBuilder();
    for(String s: commands){
        completeCommand.append(s);
        completeCommand.append(" ");
    }
    completeCommand.append(" > \"");
    completeCommand.append(outputDir + File.separator + outputFileName);
    completeCommand.append("\"");
    File fileOutputDir = new File(outputDir);
    fileOutputDir.mkdirs();

    Files.writeString(Path.of(outputDir + File.separator + scriptName),
            completeCommand.toString(),
            new OpenOption[]{StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE,
                    StandardOpenOption.CREATE});

    ProcessBuilder processBuilder = new ProcessBuilder("bash", "\"" + outputDir + File.separator + scriptName + "\"");
    Process p = processBuilder.start();
    pid = p.pid();
    p.waitFor();
    return pid;
} catch (IOException | InterruptedException e) {
    log.error("Error in running join command" , e);
    return pid;
}

Когда я попытался использовать bash -c, я просто изменил оператор ProcessBuilder, как показано ниже:

ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", completeCommand.toString());

Это не вызывает ошибок, но создает пустой файл.

Как я могу решить эту проблему?

Любая помощь или предложения были бы замечательными.

Спасибо

@DuncG, я отредактировал вопрос, указав соответствующие детали, как и требовалось. Спасибо

Arun Aranganathan 03.04.2021 11:22

Опубликованный вами код - нет a минимальный воспроизводимый пример. Что такое переменная commands в петле for? Помните, что обычно вам нужно разбить команду на отдельные слова и создать List или массив из этих слов и передать этот List (или массив) конструктору ProcessBuilder. Думали ли вы о написании сценария оболочки и запуске этого сценария с ProcessBuilder?

Abra 03.04.2021 11:30

@Abra, Прямо сейчас пишу команду в скрипт и выполняю скрипт. Я пытаюсь пропустить этот шаг. Является ли это возможным ? Я постараюсь перепостить код, чтобы он был минимальным и воспроизводимым.

Arun Aranganathan 03.04.2021 11:45

Трудно ответить, не увидев commands, скорее всего, это связано с побегом. Вы игнорируете сообщения об ошибках при запуске processBuilder.redirectOutput(stdout); и processBuilder.redirectErrorStream(true);.

DuncG 04.04.2021 12:05
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
54
0

Другие вопросы по теме

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