Печать строк, для которых элемент, повторенный в одном поле, связан с другим элементом, повторенным в другом поле - PullRequest
0 голосов
/ 02 октября 2018

У меня есть файл с разделителями табуляции:

scaffold_991    201     SYT3
scaffold_991    9396    SYT3
scaffold_991    11241   SYT3
scaffold_991    204     A
scaffold_991    939     A
scaffold_991    1141    A
scaffold_3006   610     TXNL4A
scaffold_3006   614     TXNL4A
scaffold_82     3098096 TXNL4A
scaffold_82     3100933 TXNL4A
scaffold_997    667     SPNS1
scaffold_997    1241    SPNS1
scaffold_997    2722    SPNS1
scaffold_997    3618    SPNS1
scaffold_997    9410    SPNS1
scaffold_997    18724   SPNS1

...

Мне нужно напечатать все строки, для которых имена в поле 3 (SYT3, TXNL4A, SPNS1, ...) не связаны с одним и тем же элементом в поле 1.

Так что вывод будет:

scaffold_3006   610     TXNL4A
scaffold_3006   614     TXNL4A
scaffold_82     3098096 TXNL4A
scaffold_82     3100933 TXNL4A

Или, если это проще, это также должно работать:

scaffold_991    201     SYT3
scaffold_991    9396    SYT3
scaffold_991    11241   SYT3
scaffold_991    204     A
scaffold_991    939     A
scaffold_991    1141    A
scaffold_997    667     SPNS1
scaffold_997    1241    SPNS1
scaffold_997    2722    SPNS1
scaffold_997    3618    SPNS1
scaffold_997    9410    SPNS1
scaffold_997    18724   SPNS1

другими словами, один и тот же повторяющийся элемент в столбце 3 должен быть связан с повторениями одного и того же элемента в столбце 1.

Я не смог найти подобный вопрос и не знаю достаточно, чтобы попробоватьсамостоятельно.

У меня также есть список уникальных элементов в столбце 3 (SYT3, TXNL4A, SPNS1).

И я заметил, что порядок 1-го столбца будет разбивать повторения одного и того же элемента в столбце 3только если этот элемент объединен с более чем одним каркасом, что приводит к:

scaffold_82     3098096 TXNL4A
scaffold_82     3100933 TXNL4A
scaffold_991    201     SYT3
scaffold_991    9396    SYT3
scaffold_991    11241   SYT3
scaffold_991    204     A
scaffold_991    939     A
scaffold_991    1141    A
scaffold_997    667     SPNS1
scaffold_997    1241    SPNS1
scaffold_997    2722    SPNS1
scaffold_997    3618    SPNS1
scaffold_997    9410    SPNS1
scaffold_997    18724   SPNS1
scaffold_3006   610     TXNL4A
scaffold_3006   614     TXNL4A

...

Я предполагаю идентифицировать случаи, когда данный элемент в столбце 3 повторяется по крайней мере секундувремя в другом месте в файле (разделенное другим элементом) было бы другим способом думать об этом:

Чтобы я мог получить вывод:

scaffold_3006   610     TXNL4A
scaffold_3006   614     TXNL4A

иможет затем удалить все строки, содержащие TXNL4A.

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

С GNU awk для истинных многомерных массивов:

$ awk '
    { map[$3][$1] = map[$3][$1] $0 ORS }
    END {
        for (f3 in map) {
            if (length(map[f3]) > 1) {
                for (f1 in map[f3]) {
                    printf "%s", map[f3][f1]
                }
            }
        }
    }
' file
scaffold_82     3098096 TXNL4A
scaffold_82     3100933 TXNL4A
scaffold_3006   610     TXNL4A
scaffold_3006   614     TXNL4A
0 голосов
/ 02 октября 2018

Это может сработать (хотя, возможно, есть и лучшее решение):

awk '{a[$3][$1][$0]=1}END{for (i in a) if (length(a[i])>1) for (j in a[i]) for (k in a[i][j]) print k}' file
  • a[$3][$1][$0]=1} создать индекс для строк, сгруппированных по $3 и $1
  • for (...) for (...) for (...) печатает все строки в группе, где имеется более одной $1 для $3

Вывод:

scaffold_82     3100933 TXNL4A
scaffold_82     3098096 TXNL4A
scaffold_3006   614     TXNL4A
scaffold_3006   610     TXNL4A
0 голосов
/ 02 октября 2018

Я думаю, что ваша проблема может быть просто сведена к поиску тех значений в field3, для которых значения в field1 не совпадают.Таким образом, для каждого значения в field3 вам нужно проверить, все ли значения в field1 для этого field3 одинаковы, а если нет, вы должны распечатать все строки с этим field3.

Сохранение вводав input.txt я могу:

cut -f 3 input.txt | sort -u |                              # get all unique fields from column 3
while read -r field3; do                                    # for each field in column 3
    tmp=$(grep $'\t'"$field3"'$' input.txt)                 # I get only values for this column                                         
    if [ "$(<<<"$tmp" cut -f1 | uniq | wc -l)" -ne 1 ]; then  # if the values in the column1 are not unique
        <<<"$tmp" cat                                          # then print all the values of column 3
    fi
done

, но я чувствовал, что многократное чтение файла в цикле не подходит для большого файла, поэтому я придумал это:

awk '{print > "'"$tmpd"'/"$3}' input.txt                        # split the file to multiple files depending on column3 value
find "$tmpd" -type f | while read -r f; do                      # do the job for each splitted file
    if [ "$(cut -f1 "$f" | sort -u | wc -l)" -ne 1 ]; then
        cat "$f"
    fi
done

Если порядок значений является ценным, вам необходимо сначала получить все значения столбца3 для печати, а затем использовать grep для их печати:

grep "$(
    # this is the same as the first method, but it just prints values of column 3
    cut -f 3 input.txt | sort -u | while read -r field3; do
        tmp=$(grep $'\t'"$field3"'$' input.txt)
        if [ "$(<<<"$tmp" cut -f1 | uniq | wc -l)" -ne 1 ]; then
            printf "%s\n" "$field3"
        fi
    # then from values of column3 the grep filter argument is constructed to filter out only those values of the file
    done | sed 's/\(.*\)/\t\1$/' | sed -z 's/\n/\\|/g;s/\\|$//'
)" input.txt

Живая версия доступна на tutorialspoints .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...