0

私は awk で最初の試みを行っているところですが、おそらく簡単な質問が 1 つあります。ディレクトリを一覧表示し、文字列に基づいて一覧から情報を抽出しようとしています。私が試している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知っておく必要がある変数を指定する必要があります。
に変数を渡すには、 for eachawkを使用します。-v

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

awkvars は必要なく直接使用でき$ます。
それらのprint間のスペースは無視されるため、実際のスペースを引用する必要があります。したがって、現在の方法では、最初のフィールド ( $1) が正確に一致するかどうかをチェックします ( ==) ' y m' は ' ' に展開され${year}${month}ます。一致した場合、2 番目のフィールド ( $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
于 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

それはあなたが探しているものですか?%を使用したパラメータ展開#は、bash だけでなく従来の bourne シェルでも機能するため、移植性が非常に高いことに注意してください。

本当に 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を使用して日付をフォーマットすると、最小の労力で先行ゼロのある 1 桁の月を処理できることに注意してください。

于 2012-09-11T12:20:18.510 に答える