
次の形式のファイルがあります。
ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213
ABCD ASADSADSFSSDSSD 09:24:50
デフォルトでは、最初のフィールドを除くすべてのフィールドは異なります。
要件:各行にタイムスタンプがあることを望みます。タイムスタンプが欠落している行がある場合は、前の行のタイムスタンプを欠落している行の最後に追加したいと思います(上記の例の4行)。この目標をどのように達成できますか?
答え1
これにより、awk
トリックを実行できます。
awk '{
if ( $NF ~ /[0-9]+:[0-9]+:[0-9]+/ ) {
lasttime = $NF
print
} else {
print $0, lasttime
}
}' < myfile.txt
答え2
場合に備えてbashソリューションがあります。単一のアイテムを使用しますawk
が、必要に応じてリファクタリングできます。
while read line ; do
ncol=$(echo "$line" | awk '{print $NF}')
if [[ "$ncol" == *:*:* ]]; then
tmstmp="$ncol"
echo "$line"
continue
fi
echo "$line $tmstmp"
done < 82031.txt
ファイルには82031.txt
次の内容が含まれます。
ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213
ABCD ASADSADSFSSDSSD 09:24:50
上記のスクリプトを実行すると、次の結果が生成されます。
ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213 09:24:42
ABCD ASADSADSFSSDSSD 09:24:50
純粋なBashソリューション
これはBash専用の選択肢です。awk
.txtファイルの入力行から最後の列を抽出する代わりに、read
ループ内でBashコマンドを使用しますwhile
。これらのオプションは-ra
バックスラッシュをエスケープ文字(-r
)で無効にし、-a
区切り文字を使用して入力を分割し、$IFS
各原子のテキストを配列の要素に配置します${line[@]}
。
while IFS=" " read -ra line ; do
ncol="${line[@]: -1:1}"
if [[ "$ncol" == *:*:* ]]; then
tmstmp="$ncol"
echo "${line[@]}"
continue
fi
echo "${line[@]} $tmstmp"
done < 82031.txt
このビットは${line[@]: -1:1}
配列の最後の列を抽出します${line[@]}
。
答え3
別のbashソリューション
[[ ! -f $1 ]] && { echo -e "\tUsage:\t\n\t\t$0\t<input_file>\n"; exit 1; }
while read -ra line;
do
if [[ ${line[@]} =~ [0-9]+:[0-9]+:[0-9]+ ]]; then
echo ${line[@]}
lasttime=${line[@]: -1:1}
else
echo ${line[@]} $lasttime
fi
done < $1