我只是用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
可能是一些简单的语法错误,任何帮助都会受到赞赏。
由于
答案 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
格式化日期可让您以最小的努力处理前导零的单位数月份。