Как сравнить 1-й столбец двух файлов и, если строки совпадают, вывести «true» [дубликат]

La única forma de hacer coincidir una cadena explícita es citarla:

[[ $var =~ 'quux' ]]

Incluso si la cadena contiene caracteres especiales (especiales para el shell [a])
sin que el caparazón los expanda o los interprete [b]:

$ var='^abcd'
$ [[ $var =~ '^ab' ]] && echo yes || echo no
yes

Si realmente necesitamos permitir (shell )caracteres especiales y permitir que el shell los interprete como una expresión regular, no deberían -entrecomillarse.

$ var='abcd'
$ [[ $var =~ ^ab ]] && echo yes || echo no
yes

Pero las cadenas sin comillas crean nuevos problemas, como con los espacios:

$ var='ab cd'
$ [[ $var =~ ^ab cd ]] && echo yes || echo no
bash: syntax error in conditional expression
bash: syntax error near `cd'

Para resolverlo, todavía necesitamos citar caracteres especiales:

$ var='ab cd'
$ [[ $var =~ ^"ab cd" ]] && echo yes || echo no
yes

$ [[ $var =~ ^ab\ cd ]] && echo yes || echo no
yes

Otros ejemplos:

[[ "a b"  =~  ^a\ b$ ]] && echo yes
[[ "a|b"  =~  ^a\|b$ ]] && echo yes
[[ "a&b"  =~  ^a\&b$ ]] && echo yes

Almacenar la expresión regular dentro de una variable evita todos esos problemas de cotización.

$ regex='^a b$'
$ [[ "a b" =~ $regex ]] && echo yes
yes

[un]Lista de caracteres especiales de shell(|&;()<>spacetabnewline).

[b]Esto es cierto desde la versión bash bash -3.2 -alfa (bajo "3.Nuevas funciones en Bash" título):

f. Quoting the string argument to the [[ command's =~ operator now forces string matching, as with the other pattern-matching operators.


Copia de descripción ampliada de bash FAQ:

E14) Why does quoting the pattern argument to the regular expression matching conditional operator (=~) cause regexp matching to stop working?

In versions of bash prior to bash-3.2, the effect of quoting the regular expression argument to the [[ command's =~ operator was not specified. The practical effect was that double-quoting the pattern argument required backslashes to quote special pattern characters, which interfered with the backslash processing performed by double-quoted word expansion and was inconsistent with how the == shell pattern matching operator treated quoted characters.

In bash-3.2, the shell was changed to internally quote characters in single- and double-quoted string arguments to the =~ operator, which suppresses the special meaning of the characters special to regular expression processing ('.', '[', '\', '(', ')', '*', '+', '?', '{', '|', '^', and '$') and forces them to be matched literally. This is consistent with how the `==' pattern matching operator treats quoted portions of its pattern argument.

Since the treatment of quoted string arguments was changed, several issues have arisen, chief among them the problem of white space in pattern arguments and the differing treatment of quoted strings between bash-3.1 and bash-3.2. Both problems may be solved by using a shell variable to hold the pattern. Since word splitting is not performed when expanding shell variables in all operands of the [[ command, this allows users to quote patterns as they wish when assigning the variable, then expand the values to a single string that may contain whitespace. The first problem may be solved by using backslashes or any other quoting mechanism to escape the white space in the patterns.

Preguntas relacionadas:

Uso de una variable en una expresión regular

2
13.10.2018, 13:22
4 ответа

Аналогично моему ответу на ваш вопрос здесь

#!/bin/bash
var=$(cut -d"|" -f 1 file  | sort -k1.1n)
var1=$(cut -d"|" -f 1 file | sort -k1.1n)

if [ "$var" == "$var1" ]
then
  echo "success"
else
  exit
fi

Пояснение:

Разделитель -dв команде cutустановлен на |с -d |, поэтому cutможет видеть границы между столбцами, которые |. Затем cutможет вытащить интересующие поля в столбце #1 с флагом -f.

В этом примере мы хотим, чтобы команда sortсравнила ограниченное подмножество данных (, то есть данных в столбце #1 ). Для этого мы указали, какие поля сравнивать, используя ключ , называемый опцией -k. k1.1сортирует первое поле и игнорирует остальные столбцы. Другими словами, сортировать по столбцу #1 по столбцу #1 (, т.е. сортировать только столбец #1 ).

Согласно сортировщику

-k, --key=POS1[,POS2]   Where POS1 is the starting field position, and POS2 is the ending field position
3
27.01.2020, 21:50

Хорошо в таких условиях

  1. cat оба файла
  2. сортировать -по уникальности
  3. количество строк результатов

Если вы получили одинаковое количество строк в обоих файлах, вы добились успеха.

N1=$(cat file1 |wc -l) ;N2=$(cat file2 |wc -l); N3=$(cat file1 file2 |sort -nu |wc -l); echo $N1 $N2 $N3

Если вам нужно получить результат :успех/выход, вы должны самостоятельно сравнить N1, N2, N3. Конечно, рекомендуется сравнивать N1 и N2 до того, как вы начнете собирать результат N3, и если они равны, и вы продолжаете, то вы сравниваете только N1 с N3 (, потому что вы начинаете считать N3 и поэтому N1== N2 ).

0
27.01.2020, 21:50

Вы можете проверить наличие непарных строк в отсортированных файлах, используя join, и проверить, является ли результат пустой строкой:

[[ -z "$(join -t '|' -v1 -v2 <(sort file1) <(sort file2))" ]] && echo "success" || echo "exit"
2
27.01.2020, 21:50

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

awk '{ print $1 }' <file1 | sort -n >file1.col1
awk '{ print $1 }' <file2 | sort -n >file2.col1

if cmp -s file1.col1 file2.col1; then
    echo 'success'
else
    echo 'exit'
fi

rm file1.col1 file2.col1

Или, используяbash-особый синтаксис:

if cmp -s <( awk '{ print $1 }' <file1 | sort -n ) \
          <( awk '{ print $1 }' <file2 | sort -n )
then
    echo 'success'
else
    echo 'exit'
fi

Команда cmp -sничего не выведет, но завершится успешно, если два ее файловых операнда имеют идентичное содержимое. Мы используем это в операторе if, чтобы выяснить, идентичны ли отсортированные 1-е столбцы двух файлов или нет.

awk '{ print $1 }'в приведенном выше коде также можно заменить на cut -d ' ' -f 1, если символ пробела после числа в первом столбце является символом пробела.

4
27.01.2020, 21:50

Теги

Похожие вопросы