bashでそれを達成する単純な方法。ここでは効率をまったく求めていません。エラー チェックはありません (まあ、必須の最低限のチェックだけです)。
このスクリプトにmyscriptという名前を付けます。2 つのパラメーター (ファイルfxLおよびfxR ) を取ります。
#!/bin/bash
tmp=''
die() {
echo >&2 "$@"
exit 1
}
on_exit() {
[[ -f $tmpL ]] && rm -- "$tmpL"
[[ -f $tmpR ]] && rm -- "$tmpR"
}
last_non_blank_line() {
sed -n -e $'/^$/ !h\n$ {x;p;}' "$1"
}
(($#==2)) || die "script takes two arguments"
fL=$1
fR=$2
[[ -r "$fL" && -w "$fL" ]] || die "problem with file \`$fL'"
[[ -r "$fR" && -w "$fR" ]] || die "problem with file \`$fR'"
# read record1, line1 of fL and fR
IFS=, read min _ < "$fL"
[[ $min =~ ^[[:digit:]]+$ ]] || die "first line of \`$fL' has a bad record"
IFS=, read t _ < "$fR"
[[ $t =~ ^[[:digit:]]+$ ]] || die "first line of \`$fR' has a bad record"
((t>min)) && ((min=t))
# read record1, last line of fL and fR
IFS=, read max _ < <( last_non_blank_line "$fL")
[[ $max =~ ^[[:digit:]]+$ ]] || die "last line of \`$fL' has a bad record"
IFS=, read t _ < <(last_non_blank_line "$fR")
[[ $t =~ ^[[:digit:]]+$ ]] || die "last line of \`$fR' has a bad record"
((t<max)) && ((max=t))
# create tmp files
tmpL=$(mktemp --tmpdir) || die "can't create tmp file"
tmpR=$(mktemp --tmpdir) || die "can't create tmp file"
trap 'on_exit' EXIT
# Read fL line by line, and only keep those
# the first record of which is between min and max
while IFS=, read a b; do
[[ $a =~ ^[[:digit:]]+$ ]] && ((a<=max)) && ((a>=min)) && echo "$a,$b"
done < "$fL" > "$tmpL"
mv -- "$tmpL" "$fL"
# Same with fR:
while IFS=, read a b; do
[[ $a =~ ^[[:digit:]]+$ ]] && ((a<=max)) && ((a>=min)) && echo "$a,$b"
done < "$fR" > "$tmpR"
mv -- "$tmpR" "$fR"
そしてそれを次のように呼び出します:
$ myscript f1L f1R
最初にスクラッチ ファイルで使用してください。無保証!自己責任!
警告。スクリプトは比較にbash演算を使用するため、各ファイルの各行の最初のレコードは、bashが処理する範囲の整数であると想定されます。
編集。最初のレコードは float であるため、 bash演算を使用する上記の方法は使用できません。非常におもしろい方法は、bashに必要なすべての操作 (最初の行を取得し、最後の行を取得し、ファイルを開くなど) を実行させ、算術部分にbcを使用することです。これにより、数値のサイズにまったく制限されなくなり ( bcは任意の精度を使用します)、浮動小数点数は大歓迎です! 例えば:
#!/bin/bash
tmp=''
die() {
echo >&2 "$@"
exit 1
}
on_exit() {
[[ -f $tmpL ]] && rm -- "$tmpL"
[[ -f $tmpR ]] && rm -- "$tmpR"
}
last_non_blank_line() {
sed -n -e $'/^$/ !h\n$ {x;p;}' "$1"
}
(($#==2)) || die "script takes two arguments"
fL=$1
fR=$2
[[ -r "$fL" && -w "$fL" ]] || die "problem with file \`$fL'"
[[ -r "$fR" && -w "$fR" ]] || die "problem with file \`$fR'"
# read record1, line1 of fL and fR
IFS=, read a _ < "$fL"
IFS=, read b _ < "$fR"
min=$(bc <<< "if($b>$a) { print \"$b\" } else { print \"$a\" }" 2> /dev/null)
[[ -z $min ]] && die "problem in first line of files \`$fL' or \`$fR'"
# read record1, last line of fL and fR
IFS=, read a _ < <( last_non_blank_line "$fL")
IFS=, read b _ < <(last_non_blank_line "$fR")
max=$(bc <<< "if($b<$a) { print \"$b\" } else { print \"$a\" }" 2> /dev/null)
[[ -z $max ]] && die "problem in last line of files \`$fL' or \`$fR'"
# create tmp files
tmpL=$(mktemp --tmpdir) || die "can't create tmp file"
tmpR=$(mktemp --tmpdir) || die "can't create tmp file"
trap 'on_exit' EXIT
# Read fL line by line, and only keep those
# the first record of which is between min and max
while read l; do
[[ $l =~ ^[[:space:]]*$ ]] && continue
r=${l%%,*}
printf "if(%s>=$min && %s<=$max) { print \"%s\n\" }\n" "$r" "$r" "$l"
done < "$fL" | bc > "$tmpL" || die "Error in bc while doing file \`$fL'"
# Same with fR:
while read l; do
[[ $l =~ ^[[:space:]]*$ ]] && continue
r=${l%%,*}
printf "if(%s>=$min && %s<=$max) { print \"%s\n\" }\n" "$r" "$r" "$l"
done < "$fR" | bc > "$tmpR" || die "Error in bc while doing file \`$fR'"
mv -- "$tmpL" "$fL"
mv -- "$tmpR" "$fR"