次のテキストを含むファイルがあるとします。
私が読んでいるソースファイルは次のとおりです。
#0 abc 2016-08-06 01:12:57 AM 9.1% 779.9M of 1G 156.3M of 1G
#1 abc 2016-08-06 02:33:47 AM 12.1% 339.9M of 1G 126.3M of 1G
以下は私が使用するスクリプトです。
#!/bin/bash
opFile="opfile.txt"
sourceFile="TestOutput"
if [[ ! -e "$opFile" ]]
then
{
touch $opFile
count=0
grep "#" "$sourceFile" | while read -r line ; do
{
cpu=$(grep "#$count" "$sourceFile" | cut -f 4 | cut -d% -f1)
mem=$(grep "#$count" "$sourceFile" | cut -f 5 | cut -dM -f1)
disk=$(grep "#$count" "$sourceFile" | cut -f 6 | cut -dM -f1)
echo -e "$cpu\n$mem\n$disk" >> "$opFile"
((count++))
}
done
}
else
{
count=0
lineCounter=0
grep "#" "$sourceFile" | while read -r line ; do
{
cpu=$(grep "#$count" "$sourceFile" | cut -f 4 | cut -d% -f1)
mem=$(grep "#$count" "$sourceFile" | cut -f 5 | cut -dM -f1)
disk=$(grep "#$count" "$sourceFile" | cut -f 6 | cut -dM -f1)
((lineCounter++))
sed ""$lineCounter"s/$/,"$cpu"/" "$opFile" | tee "$opFile"
((lineCounter++))
sed ""$lineCounter"s/$/,"$mem"/" "$opFile" | tee "$opFile"
((lineCounter++))
sed ""$lineCounter"s/$/,"$disk"/" "$opFile" | tee "$opFile"
((count++))
}
done
}
fi
これでファイルの数が変わり続けるので、 $sourceFile でスクリプトを複数回実行する必要があります。したがって、スクリプトを初めて実行すると、出力は次のようになります。
9.1
779.9
156.3
12.1
339.9
126.3
2回目の実行時(ソースファイルの値が同じであると仮定)、出力は次のようになります。
9.1,9.1
779.9,779.9
156.3,156.3
12.1,12.1
339.9,339.9
126.3,126.3
今私が使っているsedラインが正しいと確信しています。しかし、ファイルに入れるのに問題があります。 >>出力リダイレクタを使用することもできましたが、そうすると、すべての内容が新しい行に印刷されます。 Teeは予期しない方法で動作しますが、時には正しい操作を実行することもあり、他の場合は私のopfile.txtが空です。 sed出力をファイルに正しく入れる方法についてのアイデアはありますか?いいえ、好ましくは標準出力に何も表示したくありません。
ありがとうございます!
ベストアンサー1
エラーは、私が読んでいるファイルに書き込もうとしているということです。したがって、>を使用してファイルに書き込むときにファイルが開かれると、sedが内容を入れる前にファイルが切り捨てられて空のファイルになります(これが私が考えたものです。私が間違っている場合は修正してください)。同様のロジックがteeが予期せず動作する理由であるに違いありません。
最後に、stackoverflowの友達が提案したソリューションは、これをより簡単な方法で達成します。
paste -d, output.txt <(grep -oP '[0-9.]+(?=%)|[0-9.]+(?=[A-Z]+ of)' source.txt) > tmp ; mv tmp output.txt
したがって、これらのダーティ読み取り問題が発生するのを防ぐために一時ファイルを使用します。助けてくれてありがとう。