简体   繁体   English

awk在bash脚本中读取字段

[英]Awk reading fields in a bash script

I'm trying to read two text files so I can check if some fields are the same in both files. 我正在尝试读取两个文本文件,以便检查两个文件中的某些字段是否相同。 I can easily extract the fields in command line but something goes wrong when doing from a bash script. 我可以轻松地在命令行中提取字段,但是从bash脚本执行操作时会出现问题。

I generate the file (list of files) in a for loop (tried echo and printf commands) 我在for循环中生成文件(文件列表)(尝试过echo和printf命令)

printf "$servidor1$gfs1_dir$gfs1_file\n" >> server1

You can see the output of cat command 你可以看到cat命令的输出

cat server1

ftp://server/pub/data/nccf/com/gfs/prod/gfs.2014011400/gfs.t00z.pgrbf00.grib2
ftp://server/pub/data/nccf/com/gfs/prod/gfs.2014011400/gfs.t00z.pgrbf06.grib2

If I try from the command line it runs fine. 如果我从命令行尝试它运行正常。 Two lines/records in the file are shown: 显示文件中的两行/记录:

awk 'BEGIN { FS="/"} {print $11}' server1

gfs.t00z.pgrbf00.grib2
gfs.t00z.pgrbf06.grib2

But if I want to set FNR there comes the error (in the script awk it is used to build a variable named fremote ) 但是,如果我想设置FNR,则会出现错误(在脚本awk中,它用于构建名为fremote的变量)

awk 'BEGIN { FS="/"} { RS="\n"} {FNR == 1} {print $11}' server1

gfs.t00z.pgrbf00.grib2
gfs.t00z.pgrbf06.grib2

The same occurs when I create the fremote var in the bash script (i stands for the loop variable in the script) 当我在bash脚本中创建fremote var时会出现同样的情况(我代表脚本中的循环变量)

i=1
fremote=`awk -v i=$i 'BEGIN { FS="/"} { RS="\n"} {FNR == i} {print $11}' servidor1-file.list`

echo $fremote

gfs.t00z.pgrbf00.grib2 gfs.t00z.pgrbf06.grib2

Maybe it is related with the way server1 file is created, maybe how it is accessed by awk. 也许它与server1文件的创建方式有关,也许与awk如何访问它有关。 I can't find the right point. 我找不到正确的观点。

Thanks in advance for your help. 在此先感谢您的帮助。 I'll go on working o this issue and post the answer if found. 我将继续处理这个问题并发现答案。

EDIT 编辑

From the comments I add the code in the bash script where awk is invoked (hope it helps to understand what I'm trying). 从评论中我添加了调用awk的bash脚本中的代码(希望它有助于理解我正在尝试的内容)。 I have two files, list of local files and list of remote files in the server. 我有两个文件,本地文件列表和服务器中的远程文件列表。 I try to build two vars flocal and fremote to check if they are the same. 我尝试建立两个vars flocal和fremote以检查它们是否相同。 Maybe there are easier and smarter ways to check. 也许有更简单,更智能的方法来检查。

while [ $i -le $nlocal ]  
   do
   flocal=`awk -v i=$i 'FNR == i {print $1}' lista.local`
   fremote=`awk -v i=$i 'BEGIN { FS="/"} {FNR == $i} {print $11}' $2`

   if [ "$flocal" != "$fremote" ]; then 
      echo "Some file missing"  >> $log
      flag_check_descarga=0
   else
      contador=$(($contador + 1))
      echo $contador "Download OK" $flocal  >> $log
   fi
   i=$(( $i + 1 ))
done

Your syntax is wrong. 你的语法错了。

awk -v i="$i" 'BEGIN { FS="/"; RS="\n"}
    FNR == i {print $11}' server1

The BEGIN { ... } block contains actions to perform when the script is starting. BEGIN { ... }块包含脚本启动时要执行的操作。 The FNR==i { ... } block contains actions to perform when reading the *i*th line of a file. FNR==i { ... }块包含在读取文件的第i行时要执行的操作。

An unconditional block { ... } contains actions to perform unconditionally, ie for every input line. 无条件块{ ... }包含无条件执行的操作,即每个输入行。 But FNR==i is not a meaningful action; FNR==i不是一个有意义的行动; it is just a boolean which is true when the line number of the file is equal to i . 它只是一个布尔值,当文件的行号等于i时为true。 It is an excellent condition but as an action it doesn't do anything (that you can detect from the outside). 这是一个很好的条件,但作为一个动作,它没有做任何事情(你可以从外面发现)。

However, the task you appear to be trying to solve would be easier to solve with a single Awk script -- the one posted by @EtanReisner in a comment looks good to me -- or just 但是,您似乎试图解决的任务使用单个Awk脚本更容易解决 - @EtanReisner在评论中发布的那个对我来说很好 - 或者只是

comm -23 <(sort lista.remote) <(sort lista.local)

or even, if the files are already sorted, 或者甚至,如果文件已经排序,

comm -23 lista.local lista.remote

Wrapping up, you could end up with something like 总结一下,你最终会得到像这样的东西

sort -o lista.local lista.local  # make sure lista.local is sorted
awk -F/ '{ print $11 }' server1 |
sort |
comm -23 - lista.local

In keeping with the Unix spirit, this will quietly succeed if there are no differences, and fail (exit with a non-zero exit code) and print the missing entries if something is missing. 为了与Unix精神保持一致,如果没有差异,这将悄然成功,并且失败(以非零退出代码退出)并在缺少某些内容时打印缺少的条目。

If you want to print the successfully downloaded files as well, just cat lista.local , or maybe something like sed 's/^/Successfully downloaded /' lista.local 如果你想打印成功下载的文件,只需要cat lista.local ,或者像sed 's/^/Successfully downloaded /' lista.local

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM