Проблема здесь в том, что первый вызов comm
будет читать до конца обоих входных файлов.
Поскольку вы хотели бы иметь возможность предоставлять каналы в качестве входных данных (вместо " real file), вам нужно будет прочитать входные данные только один раз, а затем предоставить их в качестве входных данных для последующих команд ... С конвейерами, как только данные читаются, они исчезают и не поступаютназад.
Например:
#!/bin/bash -eu
# cleanup temporary files on exit
trap 'rm ${TMP_FILE1:-} ${TMP_FILE2:-}' EXIT
TMP_FILE1=$(mktemp)
cat < $1 > $TMP_FILE1
TMP_FILE2=$(mktemp)
cat < $2 > $TMP_FILE2
only1=$(comm -23 $TMP_FILE1 $TMP_FILE2 | wc -l)
only2=$(comm -13 $TMP_FILE1 $TMP_FILE2 | wc -l)
common=$(comm -12 $TMP_FILE1 $TMP_FILE2 | wc -l)
echo -e "${only1} only in $1"
echo -e "${only2} only in $2"
echo -e "${common} in both"
Если ваши файлы достаточно малы, вы можете прочитать их в переменных:
#!/bin/bash -eu
FILE1=$( < $1 )
FILE2=$( < $2 )
only1=$(comm -23 <( echo "$FILE1" ) <( echo "$FILE2" ) | wc -l)
only2=$(comm -13 <( echo "$FILE1" ) <( echo "$FILE2" ) | wc -l)
common=$(comm -12 <( echo "$FILE1" ) <( echo "$FILE2" ) | wc -l)
echo -e "${only1} only in $1"
echo -e "${only2} only in $2"
echo -e "${common} in both"
Также обратите внимание, что comm
работает только с отсортированными данными ... что означает, что вы, вероятно, захотите использовать sort
на входах, если вы не полностью осведомлены о последствияхиспользуя несортированные входы.
sort < $1 > $TMP_FILE1
FILE1=$( sort < $1 )