Как запустить CURL из инструкции AWK

#shell #awk

#оболочка #awk

Вопрос:

Я пытаюсь сравнить два CSV-файла, в которых сохранен хэш файла, и пытаюсь загрузить файл с несовпадающим хэшем. Однако я не могу запустить CURL из инструкции AWK в сценарии оболочки.

 #!/bin/bash
internalurl=<internalURL>

awk -v internalurl=$internalurl 'BEGIN {
   FS = OFS = ","
}
NR == FNR {
   map[$1] = $2
   next
}
!($1 in map) || map[$1] != $2 {
   print $1

   #Upload the file to 
   system("curl -F "'fileData=@$(find download -type f -iname $1)'" -O --write-out "'uploaded %{size_upload} bytes returned status_code=|%{http_code}| in %{time_total}s.'" internalurl")
 
}' first.csv second.csv
 

В file data я ищу файл из каталога «загрузить». $1 возвращает имя файла.

Я получаю ошибку ниже вокруг ‘in’

Я получаю сообщение об ошибке "syntax error near unexpected token в ‘» -> system("curl -F "'fileData=@$(find download -type f -iname $1)'" -O --write-out "'uploaded %{size_upload} bytes returned status_code=|%{http_code}| in %{time_total}s.'" inernalurl")'

Любое предложение приветствуется!

Ответ №1:

Ваша попытка кода выдает ошибку, потому что вы используете ' внутри awk программы, которая НЕ разрешена напрямую, должна использоваться с помощью переменной или в шестнадцатеричной / восьмеричной форме только внутри awk основной программы. У меня нет полной картины того, чего вы пытаетесь достичь (похоже, это тоже выходит за рамки вопроса), поэтому я пытаюсь помочь здесь, как это исправить эту ошибку, я сделал простой тест (файл, в котором может быть любая тестовая строка) и выполнил следующее (это сделаетвызов system , который должен echo печатать curl команду в виде текста на экране для ваших целей тестирования).

 awk -v s1='47 -v internalurl=$internalurl 'BEGIN {
   FS = OFS = ","
}
{
   system("echo "curl -F " s1 "fileData=@$(find download -type f -iname "$1")" s1 " -O --write-out "s1"uploaded %{size_upload} bytes returned status_code=|%{http_code}| in %{time_total}s." s1" internalurl"")
 
}' Input_file
 

Который выведет следующую curl команду следующим образом:

curl -F 'fileData=@' -O --write-out 'uploaded %{size_upload} bytes returned status_code=|%{http_code}| in %{time_total}s.' internalurl

Вы могли бы использовать приведенное выше решение, чтобы увидеть, что печатается (потому что в бэкэнде это только будет запущено, поэтому лучше сначала проверьте, напечатав его, правильна ли команда или нет, сначала распечатав ее), исправьте curl ошибки вашей команды, и как только вы будете довольны этим, вы можете затем поместить system("curl.....") команду в свой фактический код попытки.

Комментарии:

1. Равиндер, я могу сформировать ожидаемый CURL, используя system("echo "curl -F FileData=@$(find download -type f -iname "$1") -O --write-out "s1"uploaded %{size_upload} bytes returned status_code=|%{http_code}| in %{time_total}s."s1" "new""") , спасибо. Однако моя следующая задача — прочитать результат снаружи в shellscript, чтобы я мог обработать его дальше.

2. @mansingshinde, я не проверял, может быть, вы могли бы использовать `> outputfile` внутри самой системной команды, убедитесь, что вы поместили ее внутрь " , так как это будет рассматриваться как строка для awk . Но если это становится слишком сложным, тогда лучше использовать решение awk bash, предложенное анубхавой, сэр, приветствую.

3. Спасибо, Равиндер за вашу помощь, решение, предложенное Анубхавой, сработало для меня, мне пришлось его немного подправить, я сохраняю весь AWK в переменной, поскольку, поскольку в инструкции AWS я вывожу $ 1, значение этой переменной становится тем, которое я ожидал. Еще раз спасибо.

4. @mansingshinde, добро пожаловать, продолжайте учиться и продолжайте публиковать хорошие вопросы и ответы

Ответ №2:

Я предлагаю разделить функциональные возможности, т. е.

  1. Позвольте awk обрабатывать текстовые файлы, разделенные на строки и столбцы
  2. Пусть shell запускаются внешние утилиты на выходе awk

Вы можете рассмотреть следующее awk xargs решение:

 #!/bin/bash
internalurl=<internalURL>

awk 'BEGIN {
   FS = OFS = ","
}
NR == FNR {
   map[$1] = $2
   next
}
!($1 in map) || map[$1] != $2 {
   print $1 
}' first.csv second.csv |
xargs -I {} find download -type f -iname '{}' |
curl -F 'file=@-' -O --write-out 
'uploaded %{size_upload} bytes returned status_code=|%{http_code}| in %{time_total}s.' "$internalurl"
 

Комментарии:

1. анубхава, я попробовал использовать -iname ‘{$1}’, поскольку $1 из AWK возвращает имя файла. Но, похоже, не берет трубку. Как бы мне получить значение в 1 доллар и перейти к команде find. Извините за прямой вопрос, но я все же даю попробовать.

2. не бери в голову! Я могу сохранить весь оператор AWK в переменной, чтобы таким образом получить из нее значение. Однако мое требование состоит в том, чтобы выполнять дальнейшие операции с каждым экземпляром (в данном случае с файлом). Когда я сохраняю его как переменную, он возвращает имя файлов, я подумываю преобразовать его в массив, а затем выполнить остальную часть операции. Если у вас есть какой-нибудь лучший подход, пожалуйста, предложите. Ценю вашу помощь.

3. Анубхава — Неважно! Я использовал тот же подход, что и вы, и он действительно помогает при выполнении этих команд вне инструкции AWK. Я сохраняю выходные данные AWK в переменной и передаю их в CURL.

Ответ №3:

Как указано выше. Проблема в том, что ваше $1 поле не расширяется в system функции, а " кавычки не сбалансированы и ' не сбалансированы.

Все вхождения $1 в curl команде должны быть заменены на "$1"

Все кавычки в curl команде необходимо заменить на "