Donc, fondamentalement, ce que je veux faire est de comparer deux fichiers ligne par colonne 2. Comment pourrais-je accomplir cela?
Fichier_1.txt:
User1 US
User2 US
User3 US
Fichier_2.txt:
User1 US
User2 US
User3 NG
Fichier de sortie:
User3 has changed
command-line
text-processing
Roboman1723
la source
la source
diff "File_1.txt" "File_2.txt"
Réponses:
Regardez dans la
diff
commande. C'est un bon outil, et vous pouvez tout lire en tapantman diff
dans votre terminal.La commande que vous voudrez faire est celle
diff File_1.txt File_2.txt
qui affichera la différence entre les deux et devrait ressembler à ceci:Une note rapide sur la lecture du résultat de la troisième commande: Les "flèches" (
<
et>
) font référence à la valeur de la ligne dans le fichier de gauche (<
) par rapport au fichier de droite (>
), le fichier de gauche étant celui que vous avez entré. d'abord sur la ligne de commande, dans ce casFile_1.txt
En outre, vous remarquerez peut-être que la 4ème commande
diff ... | tee Output_File
renvoie les résultatsdiff
dans atee
, qui place ensuite cette sortie dans un fichier, de sorte que vous puissiez l'enregistrer pour plus tard si vous ne souhaitez pas tout afficher sur la console à la seconde près.la source
diff file1 file2 -s
. Voici un exemple: imgur.com/ShrQx9xOu vous pouvez utiliser Meld Diff
Installez en exécutant:
Votre exemple:
Comparer le répertoire:
Exemple avec plein de texte:
la source
Vous pouvez utiliser vimdiff .
Exemple:
la source
dos
et une seconde enunix
.FWIW, j'aime bien ce que j'ai avec la sortie côte à côte de diff
donnerait quelque chose comme:
la source
Vous pouvez utiliser la commande
cmp
:la sortie serait
la source
cmp
est beaucoup plus rapide quediff
si tout ce que vous voulez, c'est le code de retour.Meld
est un très bon outil. Mais vous pouvez également utiliserdiffuse
pour comparer visuellement deux fichiers:la source
Si vous vous en tenez à la question (fichier1, fichier2, fichier de sortie avec le message "a changé"), le script ci-dessous fonctionne.
Copiez le script dans un fichier vide, enregistrez-le sous
compare.py
, rendez-le exécutable, exécutez-le à l'aide de la commande suivante:Le scénario:
Avec quelques lignes supplémentaires, vous pouvez le faire soit imprimer dans un fichier de sortie, soit dans le terminal, selon que le fichier de sortie est défini:
Pour imprimer dans un fichier:
Pour imprimer dans la fenêtre du terminal:
Le scénario:
la source
Un moyen facile est d'utiliser
colordiff
, qui se comporte commediff
mais colorise sa sortie. Ceci est très utile pour lire les diffs. En utilisant votre exemple,où l'
u
option donne un diff unifié. Voici à quoi ressemble le diff colorisé:Installez
colordiff
en cours d'exécutionsudo apt-get install colordiff
.la source
Réponse supplémentaire
S'il n'est pas nécessaire de savoir quelles parties des fichiers diffèrent, vous pouvez utiliser la somme de contrôle du fichier. Il y a plusieurs façons de le faire, en utilisant
md5sum
ousha256sum
. Fondamentalement, chacun d’eux génère une chaîne contenant le hachage du fichier. Si les deux fichiers sont identiques, leur hachage sera également identique. Ceci est souvent utilisé lorsque vous téléchargez un logiciel, tel que des images iso d'installation Ubuntu. Ils sont souvent utilisés pour vérifier l'intégrité d'un contenu téléchargé.Considérons le script ci-dessous, où vous pouvez donner deux fichiers en arguments, et le fichier vous dira s’ils sont identiques ou non.
Échantillon échantillon:
Réponse plus ancienne
En outre, il existe une
comm
commande qui compare deux fichiers triés et génère une sortie en 3 colonnes: la colonne 1 pour les éléments uniques au fichier n ° 1, la colonne 2 pour les éléments uniques au fichier n ° 2 et la colonne 3 pour les éléments présents dans les deux fichiers.Pour supprimer l'une ou l'autre colonne, vous pouvez utiliser les commutateurs -1, -2 et -3. Utiliser -3 montrera les lignes qui diffèrent.
Ci-dessous, vous pouvez voir la capture d'écran de la commande en action.
Une seule condition est requise: les fichiers doivent être triés pour pouvoir être comparés correctement.
sort
La commande peut être utilisée à cette fin. Ci-dessous, une autre capture d'écran, où les fichiers sont triés puis comparés. Les lignes commençant à gauche près de File_1 seulement, les lignes commençant à la colonne 2 appartiennent à File_2 uniquementla source
Installer git et utiliser
Et vous obtiendrez une sortie dans un joli format coloré
Installation de Git
la source
colcmp.sh
Compare les paires nom / valeur dans 2 fichiers au format
name value\n
. Écrit lename
àOutput_file
si changé. Nécessite bash v4 + pour les tableaux associatifs .Usage
Fichier de sortie
Source (colcmp.sh)
Explication
Décomposition du code et de sa signification, au mieux de ma compréhension. Je me félicite des modifications et des suggestions.
Comparaison de fichier de base
cmp définira la valeur de $? comme suit :
J'ai choisi d'utiliser une instruction case .. esac to evalute $? parce que la valeur de $? change après chaque commande, y compris test ([).
Sinon, j'aurais pu utiliser une variable pour conserver la valeur de $? :
Ci-dessus fait la même chose que la déclaration de cas. IDK que j'aime mieux.
Effacer la sortie
L'option ci-dessus efface le fichier de sortie. Par conséquent, si aucun utilisateur ne change, le fichier de sortie sera vide.
Je le fais dans les instructions case afin que le fichier de sortie reste inchangé en cas d'erreur.
Copier le fichier utilisateur dans un script shell
Ci-dessus copie File_1.txt dans le répertoire de départ de l'utilisateur actuel.
Par exemple, si l'utilisateur actuel est john, la procédure ci-dessus serait identique à cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh.
Échapper à des caractères spéciaux
En gros, je suis paranoïaque. Je sais que ces caractères peuvent avoir une signification particulière ou exécuter un programme externe lorsqu'ils sont exécutés dans un script dans le cadre d'une affectation de variable:
Ce que je ne sais pas, c'est combien je ne sais pas à propos de bash. Je ne sais pas quels autres personnages pourraient avoir une signification particulière, mais je veux leur échapper avec une barre oblique inverse:
sed peut faire beaucoup plus que la correspondance de motif d'expression régulière . Le modèle de script "s / (trouver) / (remplacer) /" effectue spécifiquement la correspondance de modèle.
"s / (trouver) / (remplacer) / (modificateurs)"
en anglais: saisir toute ponctuation ou caractère spécial en tant que groupe de caputures 1 (\\ 1)
en anglais: préfixe tous les caractères spéciaux avec une barre oblique inverse
en anglais: si plus d'une correspondance est trouvée sur la même ligne, remplacez-les toutes
Commentez tout le script
Ci-dessus utilise une expression régulière pour préfixer chaque ligne de ~ / .colcmp.arrays.tmp.sh avec un caractère de commentaire bash ( # ). Je le fais parce que plus tard, j'ai l'intention d'exécuter ~ / .colcmp.arrays.tmp.sh en utilisant la commande source et parce que je ne sais pas avec certitude le format entier de File_1.txt .
Je ne veux pas exécuter accidentellement du code arbitraire. Je pense que personne ne le fait.
"s / (trouver) / (remplacer) /"
en anglais: capturez chaque ligne en tant que groupe de capacités 1 (\\ 1)
en anglais: remplacez chaque ligne par un symbole dièse suivi de la ligne remplacée
Convertir une valeur utilisateur en A1 [User] = "valeur"
Ci-dessus se trouve le noyau de ce script.
#User1 US
A1[User1]="US"
A2[User1]="US"
(pour le 2ème fichier)"s / (trouver) / (remplacer) /"
en anglais:
capturer le reste de la ligne en tant que groupe de capture 2
(remplacez) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"
A1[
pour commencer l’affectation de tableau dans un tableau appeléA1
]="
]
= fermer l'assignation de tableau, par exemple,A1[
User1]="
US"
=
= opérateur d'assignation, par exemple variable = valeur"
= valeur de citation pour capturer des espaces ... bien que, maintenant que j'y réfléchisse, il aurait été plus facile de laisser le code ci-dessus, qui supprime toutes les barres obliques inverses, ainsi que les espaces.en anglais: remplacez chaque ligne du format
#name value
par un opérateur d'affectation de tableau au formatA1[name]="value"
Rendre exécutable
Ci-dessus utilise chmod pour rendre le fichier de script de tableau exécutable.
Je ne sais pas si c'est nécessaire.
Déclarer un tableau associatif (bash v4 +)
Le capital -A indique que les variables déclarées seront des tableaux associatifs .
C'est pourquoi le script nécessite bash version 4 ou supérieure.
Exécuter notre script d'assignation de variable de tableau
Nous avons déjà:
User value
en lignes deA1[User]="value"
,Au- dessus de nous la source du script pour l'exécuter dans le shell courant. Nous faisons cela afin de pouvoir conserver les valeurs de variables définies par le script. Si vous exécutez le script directement, il génère un nouveau shell et les valeurs des variables sont perdues lorsque le nouveau shell se ferme, ou du moins c'est ce que je comprends.
Cela devrait être une fonction
Nous faisons la même chose pour 1 $ et A1 que pour 2 $ et A2 . Cela devrait vraiment être une fonction. Je pense qu'à ce stade, ce script est assez déroutant et qu'il fonctionne, donc je ne vais pas le réparer.
Détecter les utilisateurs supprimés
Boucles ci-dessus à travers des clés de tableau associatif
La méthode décrite ci-dessus utilise la substitution de variable pour détecter la différence entre une valeur non définie et une variable explicitement définie sur une chaîne de longueur nulle.
Apparemment, il y a beaucoup de façons de voir si une variable a été définie . J'ai choisi celui qui a reçu le plus de votes.
Ci-dessus ajoute l'utilisateur $ i au fichier de sortie
Détecter les utilisateurs ajoutés ou modifiés
Ci-dessus efface une variable pour que nous puissions garder une trace des utilisateurs qui n'ont pas changé.
Boucles ci-dessus à travers des clés de tableau associatif
Ci-dessus utilise la substitution de variable pour voir si une variable a été définie .
Comme $ i est la clé du tableau (nom d'utilisateur), $ A2 [$ i] doit renvoyer la valeur associée à l'utilisateur actuel à partir de File_2.txt .
Par exemple, si $ i est Utilisateur1 , ce qui précède se lit comme suit : {{A2 [User1]}]
Ci-dessus ajoute l'utilisateur $ i au fichier de sortie
Parce que $ i est la clé du tableau (nom d'utilisateur), $ A1 [$ i] doit renvoyer la valeur associée à l'utilisateur actuel à partir de File_1.txt et $ A2 [$ i] doit renvoyer la valeur à partir de File_2.txt .
Ci-dessus compare les valeurs associées pour l'utilisateur $ i à partir des deux fichiers.
Ci-dessus ajoute l'utilisateur $ i au fichier de sortie
Ci-dessus crée une liste d'utilisateurs séparés par des virgules qui n'ont pas changé. Notez qu'il n'y a pas d'espaces dans la liste, sinon la coche suivante devra être citée.
Ci-dessus indique la valeur de $ USERSWHODIDNOTCHANGE, mais uniquement s'il existe une valeur dans $ USERSWHODIDNOTCHANGE . De la manière dont cela est écrit, $ USERSWHODIDNOTCHANGE ne peut contenir aucun espace. S'il y a un besoin d'espaces, les éléments ci-dessus pourraient être réécrits comme suit:
la source