Hay dos archivos llamados "a.txt" y "b.txt", ambos tienen una lista de palabras. Ahora quiero comprobar qué palabras son adicionales en "a.txt" y no en "b.txt" .
Necesito un algoritmo eficiente ya que necesito comparar dos diccionarios.
Hay dos archivos llamados "a.txt" y "b.txt", ambos tienen una lista de palabras. Ahora quiero comprobar qué palabras son adicionales en "a.txt" y no en "b.txt" .
Necesito un algoritmo eficiente ya que necesito comparar dos diccionarios.
Respuestas:
si tienes vim instalado, prueba esto:
vimdiff file1 file2
o
vim -d file1 file2
Lo encontrarás fantástico.
Clasifícalos y usa comm
:
comm -23 <(sort a.txt) <(sort b.txt)
comm
compara archivos de entrada (ordenados) y, de forma predeterminada, genera tres columnas: líneas que son exclusivas de a, líneas que son exclusivas de b y líneas que están presentes en ambas. Al especificar -1
, -2
y / o -3
puede suprimir la salida correspondiente. Por lo tanto comm -23 a b
, solo enumera las entradas que son exclusivas de a. Utilizo la <(...)
sintaxis para ordenar los archivos sobre la marcha, si ya están ordenados, no necesita esto.
comm
es más eficiente porque hace el trabajo en una sola ejecución, sin almacenar todo el archivo en la memoria. Como está utilizando diccionarios que probablemente ya están ordenados, ni siquiera los necesita sort
. El uso, grep -f file1 file2
por otro lado, cargará todo file1
en la memoria y comparará cada línea file2
con todas esas entradas, lo cual es mucho menos eficiente. Es sobre todo útil para pequeños, sin clasificar -f file1
.
\n
también se incluirá para hacer la comparación.
Puede usar la diff
herramienta en Linux para comparar dos archivos. Puede usar las opciones --changed-group-format y --unchanged-group-format-format para filtrar los datos requeridos.
Las siguientes tres opciones pueden usarse para seleccionar el grupo relevante para cada opción:
'% <' obtiene líneas de FILE1
'%>' obtiene líneas de FILE2
'' (cadena vacía) para eliminar líneas de ambos archivos.
Por ejemplo: diff --changed-group-format = "% <" --unchanged-group-format = "" file1.txt file2.txt
[root@vmoracle11 tmp]# cat file1.txt
test one
test two
test three
test four
test eight
[root@vmoracle11 tmp]# cat file2.txt
test one
test three
test nine
[root@vmoracle11 tmp]# diff --changed-group-format='%<' --unchanged-group-format='' file1.txt file2.txt
test two
test four
test eight
Si prefiere el estilo de salida diff git diff
, puede usarlo con el --no-index
indicador para comparar archivos que no están en un repositorio git:
git diff --no-index a.txt b.txt
Utilizando un par de archivos con alrededor de 200k cadenas de nombre de archivo en cada uno, comparé (con el time
comando incorporado ) este enfoque frente a algunas de las otras respuestas aquí:
git diff --no-index a.txt b.txt
# ~1.2s
comm -23 <(sort a.txt) <(sort b.txt)
# ~0.2s
diff a.txt b.txt
# ~2.6s
sdiff a.txt b.txt
# ~2.7s
vimdiff a.txt b.txt
# ~3.2s
comm
parece ser el más rápido con diferencia, mientras que git diff --no-index
parece ser el enfoque más rápido para la salida de estilo diff.
Actualización 2018-03-25 En realidad, puede omitir el --no-index
indicador a menos que esté dentro de un repositorio git y desee comparar archivos no rastreados dentro de ese repositorio. De las páginas del manual :
Este formulario es para comparar las dos rutas dadas en el sistema de archivos. Puede omitir la opción --no-index cuando ejecuta el comando en un árbol de trabajo controlado por Git y al menos uno de los puntos de ruta fuera del árbol de trabajo, o cuando ejecuta el comando fuera de un árbol de trabajo controlado por Git.
También puede usar: colordiff : muestra la salida de diff con colores.
Acerca de vimdiff : le permite comparar archivos a través de SSH, por ejemplo:
vimdiff /var/log/secure scp://192.168.1.25/var/log/secure
Extraído de: http://www.sysadmit.com/2016/05/linux-diferencias-entre-dos-archivos.html
Además, no se olvide de mcdiff : visor de diferencias internas de GNU Midnight Commander .
Por ejemplo:
mcdiff file1 file2
¡Disfrutar!
Uso comm -13
(requiere archivos ordenados) :
$ cat file1
one
two
three
$ cat file2
one
two
three
four
$ comm -13 <(sort file1) <(sort file2)
four
Aquí está mi solución para esto:
mkdir temp
mkdir results
cp /usr/share/dict/american-english ~/temp/american-english-dictionary
cp /usr/share/dict/british-english ~/temp/british-english-dictionary
cat ~/temp/american-english-dictionary | wc -l > ~/results/count-american-english-dictionary
cat ~/temp/british-english-dictionary | wc -l > ~/results/count-british-english-dictionary
grep -Fxf ~/temp/american-english-dictionary ~/temp/british-english-dictionary > ~/results/common-english
grep -Fxvf ~/results/common-english ~/temp/american-english-dictionary > ~/results/unique-american-english
grep -Fxvf ~/results/common-english ~/temp/british-english-dictionary > ~/results/unique-british-english
sdiff -s file1 file2
fue útil.
Usando awk para ello. Archivos de prueba:
$ cat a.txt
one
two
three
four
four
$ cat b.txt
three
two
one
El awk:
$ awk '
NR==FNR { # process b.txt or the first file
seen[$0] # hash words to hash seen
next # next word in b.txt
} # process a.txt or all files after the first
!($0 in seen)' b.txt a.txt # if word is not hashed to seen, output it
Se duplican los duplicados:
four
four
Para evitar duplicados, agregue cada palabra recién encontrada en a.txt a seen
hash:
$ awk '
NR==FNR {
seen[$0]
next
}
!($0 in seen) { # if word is not hashed to seen
seen[$0] # hash unseen a.txt words to seen to avoid duplicates
print # and output it
}' b.txt a.txt
Salida:
four
Si las listas de palabras están separadas por comas, como:
$ cat a.txt
four,four,three,three,two,one
five,six
$ cat b.txt
one,two,three
tienes que hacer un par de vueltas adicionales ( for
bucles):
awk -F, ' # comma-separated input
NR==FNR {
for(i=1;i<=NF;i++) # loop all comma-separated fields
seen[$i]
next
}
{
for(i=1;i<=NF;i++)
if(!($i in seen)) {
seen[$i] # this time we buffer output (below):
buffer=buffer (buffer==""?"":",") $i
}
if(buffer!="") { # output unempty buffers after each record in a.txt
print buffer
buffer=""
}
}' b.txt a.txt
Salida esta vez:
four
five,six
diff a.txt b.txt
¿no es suficiente?