Почему мой скрипт bash помечает эту команду подстроки awk как синтаксическую ошибку, когда она работает в терминале? - PullRequest
0 голосов
/ 29 мая 2019

Я пытаюсь извлечь список дат из серии ссылок, используя функцию дампа 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'

Для контекста это часть цикла while-read, в котором $ link читается из файла. Все операции, выполняемые внутри этого цикла while при удалении команды awk, являются успешными, как и аналогичные циклы while, которые включают другие команды 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

1 Ответ

2 голосов
/ 29 мая 2019
  1. В команде sed у вас нет совпадений ', из-за отсутствия кавычек '.

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

Из Руководство gawk :

substr (строка, начало [, длина])

Возвращает длинную символьную длинную подстроку строки, начинающуюся с начала номера символа. Первый символ строки является символом номер один.48 Например, substr («вашингтон», 5, 3) возвращает «инг».

Если длина не указана, substr () возвращает весь суффикс строки, которая начинается с начала номера символа. Например, substr («вашингтон», 5) возвращает «ингтон». Весь суффикс также возвращается, если длина превышает количество оставшихся символов в строке, считая с начала символа.

Если start меньше единицы, substr () обрабатывает его так, как если бы он был один. (POSIX не указывает, что делать в этом случае: BWK awk действует так, и, следовательно, gawk тоже.) Если start больше, чем число символы в строке substr () возвращает пустую строку. Так же, если длина присутствует, но меньше или равна нулю, пустая строка возвращается.

Также я предлагаю вам объединить 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...