Ответ 1
Вот решение, которое может работать или не работать для ваших данных. Он подходит к проблеме путем выравнивания записей в файле csv по номеру строки, то есть запись 2
заканчивается в строке 2
, запись 3123
на номер строки 3123
и т.д. Отсутствующие записи/строки заполняются полями MISSING
, поэтому входные файлы будут искажены, чтобы выглядеть так:
en.csv
:
1,dog,red,car
2,MISSING,MISSING,MISSING
3,cat,white,boat
de.csv
:
1,Hund,Rot,Auto
2,Kaninchen,Grau,Zug
3,MISSING,MISSING,MISSING
sp.csv
:
1,MISSING,MISSING,MISSING
2,conejo,gris,tren
3,gato,blanco,bote
Оттуда легко вырезать интересующие столбцы и просто печатать их бок о бок с помощью paste
.
Для этого мы сначала сортируем входные файлы, а затем применяем несколько тупых магов awk
:
- Если на ожидаемом номере строки появится запись, напечатайте ее
- В противном случае напечатайте как можно больше строк, содержащих количество ожидаемых (это зависит от количества полей первой строки в файле, так же, как и те, что
join -o auto
)MISSING
, пока выравнивание не будет правильным снова - Не все входные файлы имеют одинаковое количество записей, поэтому до этого все выполняется поиск максимального значения. Затем больше строк с полями
MISSING
печатаются до тех пор, пока не будет достигнут максимум.
Код
reccut.sh
:
#!/bin/bash
get_max_recnum()
{
awk -F, '{ if ($1 > max) { max = $1 } } END { print max }' "[email protected]"
}
align_by_recnum()
{
sort -t, -k1 "$1" \
| awk -F, -v MAXREC="$2" '
NR==1 { for(x = 1; x < NF; x++) missing = missing ",MISSING" }
{
i = NR
if (NR < $1)
{
while (i < $1)
{
print i++ missing
}
NR+=i
}
}1
END { for(i++; i <= MAXREC; i++) { print i missing } }
'
}
_reccut()
{
local infiles=()
local args=( [email protected] )
for arg; do
infiles+=( "$2" )
shift 2
done
MAXREC="$(get_max_recnum "${infiles[@]}")" __reccut "${args[@]}"
}
__reccut()
{
local cols="$1"
local infile="$2"
shift 2
if (( $# > 0 )); then
paste -d, \
<(align_by_recnum "${infile}" "${MAXREC}" | cut -d, -f ${cols}) \
<(__reccut "[email protected]")
else
align_by_recnum "${infile}" "${MAXREC}" | cut -d, -f ${cols}
fi
}
_reccut "[email protected]"
Run
$ ./reccut.sh 3 en.csv 2,4 sp.csv 3 de.csv
red,MISSING,MISSING,Rot
MISSING,conejo,tren,Grau
white,gato,bote,MISSING