awk,脚本中的行尾

时间:2012-09-11 11:16:50

标签: awk

我只是用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

可能是一些简单的语法错误,任何帮助都会受到赞赏。

由于

2 个答案:

答案 0 :(得分:1)

您需要提供awk您需要了解的变量 要将变量传递给awk,请为每个变量使用-v

awk -v y="$year" -v m="$month" 'BEGIN { FS = "." } $1 == y m { print $2 }' file
然后可以直接使用

awk个变量,不需要$print一样,它们之间的空间将被忽略,必须引用一个真实的空间。 现在的方式是,它会检查第一个字段($1)是否完全匹配(==)'y m',并将其扩展为“${year}${month}”。如果匹配发生,则打印第二个字段($2)。


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

condition { action [; action ..] }

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


说了这么多,我会用纯Bash来做你正在做的事情:

while IFS='.' read -r ym f e
do 
    printf '%8s: %s\n' "year"  "${ym%??}"   \
                       "month" "${ym#????}" \
                       "file"  "$f"         \
                       "ext"   "$e"
done < file

答案 1 :(得分: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格式化日期可让您以最小的努力处理前导零的单位数月份。