Итак:
- сначала извлеките сопоставимую часть файлов - т.е. первые 3 поля
- затем сортируйте их для извлечения уникальных строк в файлах
- добавить уникальные строки из обоих файлов с суффиксом
," "
- распечатать уникальные строки из файла A.txt с файлом B.txt, отсортировать их и поместить в файл B1.txt
- распечатать уникальные строки из файла B.txt с файлом A.txt, отсортировать их и поместить в файл A1.txt
Следующий код:
cat <<EOF >A.txt
10,1,1,"ABC"
10,1,2,"S1"
10,1,2,"ABC"
10,1,3,"baba"
10,2,1,"S2"
10,2,1,"asd"
10,2,2,"S3"
10,2,2,"dkkd"
10,2,3,"ABC"
EOF
cat <<EOF >B.txt
10,1,1,"ABC1"
10,1,2,"S1"
10,1,2,"ABC"
10,1,3,"baba"
10,2,1,"asd"
10,2,2,"S3"
10,2,2,"dkkd"
10,2,4,"bokaj"
EOF
# extract unique lines from first and second file
# hide lines common in both files
comm -3 <(
# extract 3 fields from A.txt and sort
< A.txt \
cut -d, -f1-3 |
sort
) <(
# extract 3 fields from B.txt and sort
< B.txt \
cut -d, -f1-3 |
sort
) |
# suffix with `," "` string
sed 's/$/," "/' |
# split the stream
tee >(
# extract lines unique to the first file, ie. A.txt file
grep -v $'^\t' |
# join the stream with the content of B.txt file
# also note that lines from stdin are preferred in sorting order
# over the same lines from B.txt file
# sort it using first 3 fields. Preserve sorting from B.txt file
# and put the output into B1.txt
sort -s -t, -k1,3 - B.txt \
> B1.txt
) |
# extract lines unique to the second file, ie. B.txt file
grep $'^\t' | cut -f2 |
# join the output with A.txt file
# sort it using first 3 fields, preserve sorting, put into A1.txt
sort -s -t, -k1,3 - A.txt \
> A1.txt
# verbose output
set -x
cat B1.txt
cat A1.txt
выведет:
++ cat B1.txt
10,1,1,"ABC1"
10,1,2,"S1"
10,1,2,"ABC"
10,1,3,"baba"
10,2,1," "
10,2,1,"asd"
10,2,2,"S3"
10,2,2,"dkkd"
10,2,3," "
10,2,4,"bokaj"
++ cat A1.txt
10,1,1,"ABC"
10,1,2,"S1"
10,1,2,"ABC"
10,1,3,"baba"
10,2,1,"S2"
10,2,1,"asd"
10,2,2,"S3"
10,2,2,"dkkd"
10,2,3,"ABC"
10,2,4," "
проверено на repl.it .
comm
имеет странный вывод, поскольку он не имеет суффикса со строками-разделителями, уникальными для первого файла. Поэтому я научился grep
составлять таблицы для извлечения уникальных строк, поэтому для получения уникальных строк из файлов A.txt или B.txt я делаю grep -v $'^\t'
или grep $'^\t' | cut -d2
соответственно.
При запуске comm
два раза этот скрипт может быть более многословным и более "линейным, как" (не знаю, как его назвать, без tee
):
comm -13 <(
< A.txt \
cut -d, -f1-3 |
sort
) <(
< B.txt \
cut -d, -f1-3 |
sort
) |
sed 's/$/," "/' |
sort -s -t, -k1,3 - A.txt \
> A1.txt
comm -23 <(
< A.txt \
cut -d, -f1-3 |
sort
) <(
< B.txt \
cut -d, -f1-3 |
sort
) |
sed 's/$/," "/' |
sort -s -t, -k1,3 - B.txt \
> B1.txt
И немного аккуратного 4 вкладыша:
comm -3 <(cut -d, -f1-3 A.txt | sort) <(cut -d, -f1-3 B.txt | sort) |
sed 's/$/," "/' |
tee >(grep -v $'^\t' | sort -s -t, -k1,3 - B.txt > B1.txt) |
grep $'^\t' | cut -f2 | sort -s -t, -k1,3 - A.txt > A1.txt