0

ファイル内のファイル名のリストで始まるスクリプトがあります。リスト内の各ファイルに対して、スクリプトは

  • ファイル内の行を見てください
  • その行の列 2 が---同じ行から列 4 の値を取得し、その値を使用して別のアーカイブ ファイルから欠落している値を grep し---ます (ファイル名は同じですが、場所と拡張子は異なります)。
  • 次に---、grep された値に置き換えます。

したがって、私が望む出力は元のファイルであり、すべてのインスタンスが---別の列からのルックアップに基づいて正しい値に変更されています。

これを行うために私が書いたスクリプトは次のとおりです。

#!/bin/bash
# process the files in the list
for fname in $mylist ; do
    for line in $fname ; do 
    name=$(echo $fname | awk -F"/" '{print $9}' | sed 's:.ext::g'); #getbasename to help find archive file
    dash=$(awk < "$line" '{print $2}');  #get col2 of the line (may have the "---" missing value")
    loca=$(awk < "$line" '{print $4}');  #col 4 for grepping

        if [$dash -eq "---"]; then   
            ID=$(grep -F -w "$loca" /path/archiveFiles/$name | awk '{print $2}'); #find the missing value in the relevant archive file, using $loca as the lookup key
            fixed=$(awk  -v snpID="$ID" '{OFS="\t"} {print $1,ID, $3, $4}' "$fline");
            echo "$fixed" ;
        else echo "$line" ;
        fi 
    done  >>/path/correctedFiles/$name.ext &

done
wait

スクリプトは現在、「行 XX: IDNNNN: コマンドが見つかりません」という sterror を返します行 XX はスクリプトに存在しません (実際にはスクリプトの最後の行であり、空です) IDNNNN は、grep しようとしている欠落している値の 1 つですアーカイブファイルから。この出力の解決を手伝ってくれる人はいますか? ありがとうございました

: grep をもう少し詳しく説明するためにスクリプトを編集しました; サンプル ファイルとエラー メッセージを再度編集しました: mylist:

> path/dir/file_1_17.03s.07.ext path/dir/file_1_2.51p.12.ext
> path/dir/file_2_112.07.ext path/dir/file_2_155.07.ext
> path/dir/file_13_1.5.12-13.ext

file_1_17.03s.07.extの内容(全ファイル同一形式)

>     1 ID45    0   KEY7
>     1 ID46    0   KEY45
>     1 --- 0   KEY501
>     1 ID48    0   KEY6

不足しているデータを grep するアーカイブ ファイルの内容。つまり、ファイル file_1_17.03s.07.ext については、/path/archiveFiles/file_1_17.03s.07.arc を調べます。

X1    ID45    KEY7
X2    ID46    KEY45
X3    ID47    KEY501
X4    ID48    KEY6

上記でやろうとしているのは、関連するアーカイブ ファイルの KEY 列を使用して、リスト内の各ファイルを修正し、file_1_17.03s.07.ext の内容が次のようになるようにすることです。

1 ID45    0   KEY7
1 ID46    0   KEY45
1 ID47    0   KEY501
1 ID48    0   KEY6

スクリプトの実行によるエラー。

> /var/spool/stuff: line 53: ID45: command not found /var/spool/stuff:
> line 53: ID46: command not found (and so on)

提案された修正での実行によるエラー。

/var/spool/stuff: line 53: file_1_17.03s.07: command not found
/var/spool/stuff: line 53: file_1_2.51p.12.: command not found (and so on)
4

1 に答える 1

0

これは動作する可能性のあるバージョンです(テストしていません)。これが私がそれをテストするために使用したものです。

テスト環境の作成:

mkdir out
mkdir archive
echo -e "one\ttwo\tthree\tfour\none\t---\tthree\tfour" > test.ext
echo -e "newone\tnewtwo\tnewthree\tfour" > archive/test.arc
rm out/test.ext

次のスクリプトが機能します。

#!/bin/bash

mylist="test.ext"
path_archive="./archive/"
path_out="./out/"

process_line () {
  line=$1
  name=$2
  set -- $line

  if [ "$2" == "---" ] ; then
    ID=$(grep -F -w "$4" ${path_archive}/${name}.arc | awk '{print $2}')
    echo -e "$1\t$ID\t$3\t$4"
  else
    echo "$line"
  fi
}

# process the files in the list
for fname in `cat $mylist` ; do
  echo processing $fname

  name=`basename $fname .ext`
  cat $fname | while read line ; do
    process_line "$line" "$name" >> $path_out/$name.ext
  done 
done

これset -- $lineはbashのことです。これにより、位置パラメータ ( $1$2、...) が に提供された引数に設定されset --ます。引数を指定しないとset --、定位置パラメーターの設定が解除されます。次の例を検討してください。

:~$ echo $1

:~$ set -- foo
:-$ echo $1
foo
:-$ set -- bar
:-$ echo $1
bar

for fname in `cat $mylist`; doファイル名に$mylistスペースが含まれている場合、上記は機能しません。その場合で、各行にファイル名が 1 つだけある場合は、cat $mylist | while read fname ; do代わりに実行し、$fname常に二重引用符 ( "$fname") で囲む必要があります。

出力:

$ cat test.ext
one two three   four
one --- three   four
$ cat out/test.ext
one two three   four
one newtwo  three   four

全体として、そのようなタスクには Perl または Python を使用したいと考えています。書き込みとデバッグがはるかに簡単になります。

于 2013-07-02T08:16:36.003 に答える