Почему мой сценарий bash помечает эту команду подстроки awk как синтаксическую ошибку, когда она работает в терминале?

Я пытаюсь извлечь список дат из серии ссылок, используя функцию дампа lynx и передавая вывод через grep и awk. Эта операция успешно работает в терминале и точно выводит даты. Однако, когда он помещается в сценарий оболочки, bash сообщает о синтаксической ошибке:

Scripts/ETC/PreD.sh: line 18: syntax error near unexpected token `('
Scripts/ETC/PreD.sh: line 18: ` lynx --dump "$link" | grep -m 1 Date | awk '{print substr($0,10)}' >> dates.txt'

Для контекста, это часть цикла чтения, в котором $link читается из файла. Все операции, выполняемые в этом цикле, когда команда awk удалена, выполняются успешно, как и аналогичные циклы, включающие другие команды awk.

Я знаю, что либо я неправильно понимаю, как bash обрабатывает подстановку переменных, либо как bash обрабатывает команды awk, либо какое-то их сочетание. Любая помощь будет очень признательна.

Обновлено: Shellcheck разделен на это, версия веб-сайта не находит ошибок, но моя загруженная версия выдает ошибку SC1083, в которой говорится:

This { is literal. Check expression (missing ;/\n?) or quote it.

Проверка на странице Shellcheck GitHub дает следующее:

This error is harmless when the curly brackets are supposed to be literal, in e.g. awk {'print $1'}. 
However, it's cleaner and less error prone to simply include them inside the quotes: awk '{print $1}'.

Сценарий следующий:

#!/bin/bash

while read -u 4 link
do
        IFS=/ read a b c d e <<< "$link"
        echo "$e" >> 1.txt
        lynx --dump "$link" | grep -A 1 -e With: | tr -d [:cntrl:][:digit:][] | sed 's/\With//g' | awk '{print substr($0,10)}' | sed 's/\(.*\),/\1'\ and'/' | tr -s ' ' >> 2.txt
        lynx --dump "$link" | grep -m 1 Date | awk '{print substr($0,10)}' >> dates.txt
done 4< links.txt

похоже, ошибка не в awk, вы должны поместить свой скрипт в shellcheck.net, чтобы получить синтаксическую ошибку. Кроме того, использование grep и awk в одной строке излишне,

P.... 29.05.2019 21:58

Вам нужно опубликовать сценарий, если вы хотите помочь в его отладке.

Barmar 29.05.2019 22:00

Что вы пытаетесь сделать с tr -d [:cntrl:][:digit:][] (особенно с [] в конце и без кавычек вокруг сценария)? Что вы пытаетесь сделать с sed 's/\(.*\),/\1'\ and'/'? Опубликуйте ПОЛНЫЙ минимальный скрипт, который выдает сообщение об ошибке — мы даже не видим шебанга в опубликованном вами фрагменте.

Ed Morton 29.05.2019 22:34

Какую оболочку вы использовали в шелчеке? Вы использовали правильный Шебанг?

shargors 29.05.2019 22:40

Проблема может быть в любой из 3-х программ длинной трубы. Обратите внимание, что переменная length в скрипте awk всегда равна 0.

Dudi Boy 29.05.2019 22:44

Сообщение об ошибке shellcheck, которое вы публикуете, похоже, не из кода, который вы опубликовали.

Benjamin W. 29.05.2019 22:52

@DudiBoy, к сожалению, POSIX позволяет вызывать функцию length() не только без аргументов, но даже без скобок, поэтому вы можете написать length, и это означает то же, что и length($0). Ужасно, и лично я никогда бы этого не сделал, но мы застряли с этим. В коде OP вообще нет смысла присутствовать в этом substr($0,10,length), так как это будет большее значение, которое может присутствовать после начального индекса 10 - substr($0,10) более лаконичен и семантически лучше.

Ed Morton 29.05.2019 23:44

Код, указанный здесь, имеет проблемы, но не должен вызывать указанную ошибку. Я предполагаю, что ранее в сценарии была проблема с цитированием (в одной из 12 пропущенных строк перед цитируемым разделом), которая вызывает проблему синтаксического анализа цепочки.

Gordon Davisson 29.05.2019 23:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
434
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. В команде sed у вас есть непревзойденный ' из-за некавычек '.

  2. В скрипте awk у вас есть постоянная нулевая переменная length.

Из руководство по тарабарщине:

substr(string, start [, length ])

Return a length-character-long substring of string, starting at character number start. The first character of a string is character number one.48 For example, substr("washington", 5, 3) returns "ing".

If length is not present, substr() returns the whole suffix of string that begins at character number start. For example, substr("washington", 5) returns "ington". The whole suffix is also returned if length is greater than the number of characters remaining in the string, counting from character start.

If start is less than one, substr() treats it as if it was one. (POSIX doesn’t specify what to do in this case: BWK awk acts this way, and therefore gawk does too.) If start is greater than the number of characters in the string, substr() returns the null string. Similarly, if length is present but less than or equal to zero, the null string is returned.

Также я предлагаю вам объединить grep|awk|sed|tr в один скрипт awk. И отладьте awk-скрипт с распечатками.

От:

lynx --dump "$link" | grep -A 1 -e With: | tr -d [:cntrl:][:digit:][] | sed 's/\With//g' | awk '{print substr($0,10,length)}' | sed 's/\(.*\),/\1'\ and'/' | tr -s ' ' >> 2.txt

К:

lynx --dump "$link" | awk '/With/{found=1;next}found{found=0;print sub(/\(.*\),/,"& and",gsub(/ +/," ",substr($0,10)))}' >> 2.txt

От:

lynx --dump "$link" | grep -m 1 Date | awk '{print substr($0,10,length)}' >> dates.txt

К:

lynx --dump "$link" | awk '/Date/{print substr($0,10)}' >> dates.txt

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