当我的bash脚本在终端中运行时,为什么将awk子字符串命令标记为语法错误?

时间:2019-05-29 19:53:44

标签: bash awk

我正在尝试使用lynx的dump函数从一系列链接中提取日期列表,并将输出通过grep和awk传递给管道。此操作在终端中成功完成,并准确输出日期。但是,将bash放入shell脚本时,它会声明语法错误:

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读取循环的一部分,在该循环中,正在从文件读取$ link。删除awk命令后,在while循环内进行的操作均会成功,包括其他awk命令的类似while循环也是如此。

我知道我是误解了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 个答案:

答案 0 :(得分:2)

  1. sed命令中,由于未引用',因此您没有匹配的'

  2. awk脚本中,您有恒定为零的length变量。

来自gawk manual

  

substr(string,start [,length])

     

返回字符串的长度字符长的子字符串,从字符编号start开始。字符串的第一个字符是character   数字48。例如,substr(“ washington”,5,3)返回“ ing”。

     

如果不存在长度,则substr()返回以字符号start开头的字符串的整个后缀。例如,   substr(“ washington”,5)返回“ ington”。整个后缀也   如果length大于剩余字符数,则返回   在字符串中,从字符开始算起。

     

如果start小于1,substr()会将其视为1。 (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