1

coprocさて、私は のようなリダイレクト経由またはリダイレクト経由のコプロセスを本当に使用したい状況にあります<(some command)が、残念ながら、ターゲット環境の 1 つで bash 3.2 に制限されています。つまり、私は私にできることは限られています。

コプロセスが必要な理由は、別のファイルをループしながら、1 つのファイルから行ごとに読み取る必要があるためです。

現在、私はさらに入力が必要なときにいつでもexec <6 /foo/barできるように、読み取り用にファイルを開いたままにするために使用しています。read line <&6これは正常に機能しますが、プレーンテキスト ファイルでのみ機能しますが、実際には、スクリプトを実行する前にファイルを解凍するのではなく、ファイルを圧縮したままにしたいと考えています。

また、プレーンテキストで書き込んで後で圧縮するスペースを無駄にすることなく、新しい圧縮ファイルに書き込むために同じことができる必要があります。

それで…bash 3で利用できる代替手段はありますか? 私が指摘したように、私はすでに別のファイルのループに入っているので、ループとは独立してこれを行う必要があるため、出力を単にパイプするgzip(またはzcatループにパイプする) というオプションはありません。

例を示すために、ここに私が今やっていることの簡略化されたバージョンがあります:

# Decompress compressed match-file
gzip -dc /foo/compressed.gz > /tmp/match

# Setup file handles (to keep files open for reading/writing)
exec 5< /tmp/match
exec 6> /tmp/matches

# Loop over input file (/foo/bar) for matches
read next_match <&5
while read line; do
    if [ "$line" = "$next_match" ]; then
        read next_match <&5
        echo "$line" >&6
    fi

    echo "$line"
done < /foo/bar

# Close file handles
exec <5&-
exec 6>&-
rm /tmp/match

# Compress matches and overwrite old match file
gzip -cf9 /tmp/matches /foo/compressed.gz
rm /tmp/matches

タイプミスと実際のスクリプトの一般的な無用さを許してください。私はそれをかなり単純にしたかっただけです。ご覧のとおり、問題なく動作しますが、無駄なプレーンテキスト ファイルのおかげで、最適とは言えません。

4

2 に答える 2

1

bash3.2ではプロセス置換が可能ですので、そのままご利用いただけます。

# Setup file handles (to keep files open for reading/writing)
exec 5< <( gzip -dc /foo/compressed.gz )
exec 6> >( gzip -c9 /foo/new_compressed.gz)

# Loop over input file (/foo/bar) for matches
read next_match <&5
while read line; do
    if [ "$line" = "$next_match" ]; then
        read next_match <&5
        echo "$line" >&6
    fi

    echo "$line"
done < /foo/bar

# Close file handles
exec <5&- 6>&-

# Overwrite old match file
mv /foo/new_compressed.gz /foo/compressed.gz
于 2014-01-26T21:01:49.050 に答える