0

我只是第一次尝试使用 awk 并且有一个,也许是简单的问题。我正在尝试列出一个目录并根据字符串从列表中提取一些信息。我正在尝试的 bash 脚本是:

 ls *.hdf > temporary.list
 nom2=`awk 'BEGIN {FS = "." } ; { $1 ~ /'$year$month'/ } { print $2 }' temporary.list `
 file=$year$month.$nom2.hdf 
 file2=$year$month.hdf

其中年份和月份在 for 循环中发生变化(1981 到 1985 和 01 到 12)。temporary.list 文件由 12 行组成,例如:

198201.s04m1pfv51-bsst.hdf
198202.s04m1pfv51-bsst.hdf
198203.s04m1pfv51-bsst.hdf
198204.s04m1pfv51-bsst.hdf
198205.s04m1pfv51-bsst.hdf
198206.s04m1pfv51-bsst.hdf
198207.s04m1pfv51-bsst.hdf
198208.s04m1pfv51-bsst.hdf
198209.s04m1pfv51-bsst.hdf
198210.s04m1pfv51-bsst.hdf
198211.s04m1pfv51-bsst.hdf
198212.s04m1pfv51-bsst.hdf

我想根据年月选择文件。问题是我的 awk 句子似乎没有将不同的行作为不同的寄存器,我想。脚本的输出是:

nom2 = h s04m1pfv51-bsst h s04m1pfv51-bsst h s04m1pfv51-bsst h
s04m1pfv51-bsst h s04m1pfv51-bsst h s04m1pfv51-bsst h s04m1pfv51-bsst
s04m1pfv51-bsst s04m1pfv51-bsst s04m1pfv51-bsst s04m1pfv51-bsst
s04m1pfv51-bsst 

file = 198201.h s04m1pfv51-bsst h s04m1pfv51-bsst h
s04m1pfv51-bsst h s04m1pfv51-bsst h s04m1pfv51-bsst h s04m1pfv51-bsst
h s04m1pfv51-bsst s04m1pfv51-bsst s04m1pfv51-bsst s04m1pfv51-bsst
s04m1pfv51-bsst s04m1pfv51-bsst.hdf 

file2= 198201.hdf

也许是一些简单的语法错误,任何帮助将不胜感激。

谢谢

4

2 回答 2

1

您需要提供awk您需要它知道的变量。
要将变量传递给awk,请使用-v每个变量。

awk -v y="$year" -v m="$month" 'BEGIN { FS = "." } $1 == y m { print $2 }' file

awkvars 然后可以直接使用,$不需要。
由于print它们之间的空格将被忽略,因此必须引用真实的空格。所以它现在的方式是检查第一个字段 ( $1) 是否完全匹配 ( ==) ' y m' 扩展为 ' ${year}${month}'。如果匹配发生,则$2打印第二个字段 ( )。


请记住,awk逻辑块的形式为

condition { action [; action ..] }

请注意,您周围没有花括号,condition
也不需要;在块之间,只在动作之间,但它们也不会受到伤害。
所以,{ $1 ~ /'$year$month'/ }不会按照它写的方式做任何事情。


Bash说了这么多,对于你正在做的事情,我会选择 pure :

while IFS='.' read -r ym f e
do 
    printf '%8s: %s\n' "year"  "${ym%??}"   \
                       "month" "${ym#????}" \
                       "file"  "$f"         \
                       "ext"   "$e"
done < file
于 2012-09-11T11:24:47.247 回答
1

像在 bash 脚本中那样解析文件列表是一个坏习惯,因为它与文件名中可能出现的许多特殊字符不兼容。就像语法规则一样,只有在你熟悉规则的情况下才能打破规则。:)for循环是处理文件的更好构造:

#!/bin/bash

year=1982
month=9

for filename in $(printf "%04d%02d" "$year" "$month").*.hdf; do
  nom2=${filename#*.}
  nom2=${nom2%.*}
  file2=${filename%%.*}.hdf
  printf "file=%s\nnom2=%s\nfile2=%s\n\n" "$filename" "$nom2" "$file2"
done

那是你要找的吗?请注意,参数扩展使用%#在传统的 bourne shell 和 bash 中工作,因此它非常便携。

如果你真的想使用 awk,你还有很多选择。

#!/bin/bash

year=1982
month=9

for filename in $(printf "%04d%02d" "$year" "$month").*.hdf; do
  nom2=$(awk -vym="^$year$month." -vf="$filename" 'BEGIN{if(f~ym){sub(/\..*/,"",f);print f}}')
  file="$nom2.hdf"
  printf "file=%s\nnom2=%s\nfile2=%s\n\n" "$filename" "$nom2" "$file2"
done

请注意,使用printf格式化日期允许您以最小的努力处理带有前导零的个位数月份。

于 2012-09-11T12:20:18.510 回答