Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne.
Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le
moment, je fais :
sort -u A > A.trie
sort -u B > B.trie
diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires
A.trie et B.trie ? Pour l'instant, je ne vois pas trop comment utiliser
diff au milieu d'un pipe, ni comment faire ça sans passer par diff.
Ce n'est franchement pas très important, passer par les fichiers
intermédiaires ne me dérange pas en pratique, c'est plutôt pour apprendre.
le 24/11/2007 à 02:03, mpg a écrit dans le message <fi7t8h$2vbl$ :
Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne. Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le moment, je fais :
sort -u A > A.trie sort -u B > B.trie diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires A.trie et B.trie ? Pour l'instant, je ne vois pas trop comment utiliser diff au milieu d'un pipe, ni comment faire ça sans passer par diff.
Ce n'est franchement pas très important, passer par les fichiers intermédiaires ne me dérange pas en pratique, c'est plutôt pour apprendre.
Si l'ordre dans lequel tes lignes apparaissent ne t'importe pas, tu peux utiliser le script suivant :
le 24/11/2007 à 02:03, mpg a écrit dans le message
<fi7t8h$2vbl$3@talisker.lacave.net> :
Soit deux fichiers A et B contenant chacun une liste de mots, un par
ligne. Je souhaite connaître tous les mots de A qui ne sont pas dans
B. Pour le moment, je fais :
sort -u A > A.trie
sort -u B > B.trie
diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires
A.trie et B.trie ? Pour l'instant, je ne vois pas trop comment
utiliser diff au milieu d'un pipe, ni comment faire ça sans passer par
diff.
Ce n'est franchement pas très important, passer par les fichiers
intermédiaires ne me dérange pas en pratique, c'est plutôt pour
apprendre.
Si l'ordre dans lequel tes lignes apparaissent ne t'importe pas, tu peux
utiliser le script suivant :
le 24/11/2007 à 02:03, mpg a écrit dans le message <fi7t8h$2vbl$ :
Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne. Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le moment, je fais :
sort -u A > A.trie sort -u B > B.trie diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires A.trie et B.trie ? Pour l'instant, je ne vois pas trop comment utiliser diff au milieu d'un pipe, ni comment faire ça sans passer par diff.
Ce n'est franchement pas très important, passer par les fichiers intermédiaires ne me dérange pas en pratique, c'est plutôt pour apprendre.
Si l'ordre dans lequel tes lignes apparaissent ne t'importe pas, tu peux utiliser le script suivant :
Nicolas George wrote in message <4747f1ec$0$12374$:
sort -u A > A.trie sort -u B > B.trie diff A.trie B.trie | grep '^<' grep -Fxf B A
Je remarque que ma version ne fait pas la même chose que la tienne ni celle de Benoît. Mais c'est la seule qui colle à l'énoncé que tu as donné.
Benoit Izac
Bonjour,
le 24/11/2007 à 10:40, Nicolas George a écrit dans le message <4747f187$0$12374$ :
Benoit Izac wrote in message :
open(my $a, "<", $ARGV[0]) or die "can't open $ARGV[0]: $!n"; $h{$_}++ foreach (<$a>); close($a);
open(my $b, "<", $ARGV[1]) or die "can't open $ARGV[1]: $!n"; $h{$_}-- foreach (<$b>); close($b);
Mettre le deuxième en premier, et remplacer le premier par :
print unless $h{$_};
est plus efficace et préserve l'ordre.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas précisé ce qu'il faut faire lorsque une ligne apparaît par exemple deux fois dans A et une fois dans B. Pour garder le même comportement :
print if (++$h{$_} > 0);
-- Benoit Izac
Bonjour,
le 24/11/2007 à 10:40, Nicolas George a écrit
dans le message <4747f187$0$12374$426a74cc@news.free.fr> :
Benoit Izac wrote in message <87r6igja7s@message.id>:
open(my $a, "<", $ARGV[0]) or die "can't open $ARGV[0]: $!n";
$h{$_}++ foreach (<$a>);
close($a);
open(my $b, "<", $ARGV[1]) or die "can't open $ARGV[1]: $!n";
$h{$_}-- foreach (<$b>);
close($b);
Mettre le deuxième en premier, et remplacer le premier par :
print unless $h{$_};
est plus efficace et préserve l'ordre.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas
précisé ce qu'il faut faire lorsque une ligne apparaît par exemple
deux fois dans A et une fois dans B. Pour garder le même comportement :
le 24/11/2007 à 10:40, Nicolas George a écrit dans le message <4747f187$0$12374$ :
Benoit Izac wrote in message :
open(my $a, "<", $ARGV[0]) or die "can't open $ARGV[0]: $!n"; $h{$_}++ foreach (<$a>); close($a);
open(my $b, "<", $ARGV[1]) or die "can't open $ARGV[1]: $!n"; $h{$_}-- foreach (<$b>); close($b);
Mettre le deuxième en premier, et remplacer le premier par :
print unless $h{$_};
est plus efficace et préserve l'ordre.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas précisé ce qu'il faut faire lorsque une ligne apparaît par exemple deux fois dans A et une fois dans B. Pour garder le même comportement :
print if (++$h{$_} > 0);
-- Benoit Izac
Jacques L'helgoualc'h
Le 24-11-2007, mpg a écrit :
Bonjour,
bonjour,
Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne. Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le moment, je fais :
sort -u A > A.trie sort -u B > B.trie diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires A.trie et B.trie ?
testé sous bash :
diff <(sort -u A) <(sort -u B)
Les options diff -y --suppress-common-lines peuvent servir mais ne semblent pas répondre à ta question, sauf quand B est inclus dans A. -- Jacques L'helgoualc'h
Le 24-11-2007, mpg a écrit :
Bonjour,
bonjour,
Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne.
Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le
moment, je fais :
sort -u A > A.trie
sort -u B > B.trie
diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires
A.trie et B.trie ?
testé sous bash :
diff <(sort -u A) <(sort -u B)
Les options diff -y --suppress-common-lines peuvent servir mais ne
semblent pas répondre à ta question, sauf quand B est inclus dans A.
--
Jacques L'helgoualc'h
Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne. Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le moment, je fais :
sort -u A > A.trie sort -u B > B.trie diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires A.trie et B.trie ?
testé sous bash :
diff <(sort -u A) <(sort -u B)
Les options diff -y --suppress-common-lines peuvent servir mais ne semblent pas répondre à ta question, sauf quand B est inclus dans A. -- Jacques L'helgoualc'h
Benoit Izac
Dans le message , le 24/11/2007 à 11:12, j'ai
print unless $h{$_};
est plus efficace et préserve l'ordre.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas précisé ce qu'il faut faire lorsque une ligne apparaît par exemple deux fois dans A et une fois dans B. Pour garder le même comportement :
print if (++$h{$_} > 0);
Oubliez cette remarque, le -u de sort précise ce qu'il veut en faire.
-- Benoit Izac qui va reprendre un peu de café...
Dans le message <87bq9kj6ko@message.id>, le 24/11/2007 à 11:12, j'ai
print unless $h{$_};
est plus efficace et préserve l'ordre.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas
précisé ce qu'il faut faire lorsque une ligne apparaît par exemple
deux fois dans A et une fois dans B. Pour garder le même comportement :
print if (++$h{$_} > 0);
Oubliez cette remarque, le -u de sort précise ce qu'il veut en faire.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas précisé ce qu'il faut faire lorsque une ligne apparaît par exemple deux fois dans A et une fois dans B. Pour garder le même comportement :
print if (++$h{$_} > 0);
Oubliez cette remarque, le -u de sort précise ce qu'il veut en faire.
-- Benoit Izac qui va reprendre un peu de café...
Stephane Chazelas
On Sat, 24 Nov 2007 02:03:13 +0100, mpg wrote:
Bonjour,
Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne. Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le moment, je fais :
sort -u A > A.trie sort -u B > B.trie diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires A.trie et B.trie ? Pour l'instant, je ne vois pas trop comment utiliser diff au milieu d'un pipe, ni comment faire ça sans passer par diff. [...]
comm -23 <(sort -u A) <(sort -u B)
<(...) appelé "process substitution" est une fonctionalité non-standard de zsh, bash et certains ksh.
Sinon on peut faire:
sort -u A | { exec 3<&0; sort -u B | comm -23 /dev/fd/3 -; }
-- Stephane
On Sat, 24 Nov 2007 02:03:13 +0100, mpg wrote:
Bonjour,
Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne.
Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le
moment, je fais :
sort -u A > A.trie
sort -u B > B.trie
diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires
A.trie et B.trie ? Pour l'instant, je ne vois pas trop comment utiliser
diff au milieu d'un pipe, ni comment faire ça sans passer par diff.
[...]
comm -23 <(sort -u A) <(sort -u B)
<(...) appelé "process substitution" est une fonctionalité
non-standard de zsh, bash et certains ksh.
Sinon on peut faire:
sort -u A | { exec 3<&0; sort -u B | comm -23 /dev/fd/3 -; }
Soit deux fichiers A et B contenant chacun une liste de mots, un par ligne. Je souhaite connaître tous les mots de A qui ne sont pas dans B. Pour le moment, je fais :
sort -u A > A.trie sort -u B > B.trie diff A.trie B.trie | grep '^<'
Y a-t'il moyen de faire ça sans passer par les fichiers intermédiaires A.trie et B.trie ? Pour l'instant, je ne vois pas trop comment utiliser diff au milieu d'un pipe, ni comment faire ça sans passer par diff. [...]
comm -23 <(sort -u A) <(sort -u B)
<(...) appelé "process substitution" est une fonctionalité non-standard de zsh, bash et certains ksh.
Sinon on peut faire:
sort -u A | { exec 3<&0; sort -u B | comm -23 /dev/fd/3 -; }
-- Stephane
mpg
Le (on) samedi 24 novembre 2007 11:24, Benoit Izac a écrit (wrote) :
Dans le message , le 24/11/2007 à 11:12, j'ai
print unless $h{$_};
est plus efficace et préserve l'ordre.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas précisé ce qu'il faut faire lorsque une ligne apparaît par exemple deux fois dans A et une fois dans B. Pour garder le même comportement :
print if (++$h{$_} > 0);
Oubliez cette remarque, le -u de sort précise ce qu'il veut en faire.
Ceci dit c'est une bonne remarque, car dans un premier temps je n'avais pas
envisagé le fait que A puisse contenir des doublons, donc pas mis le -u, et eu bien des surprises...
Manuel.
Le (on) samedi 24 novembre 2007 11:24, Benoit Izac a écrit (wrote) :
Dans le message <87bq9kj6ko@message.id>, le 24/11/2007 à 11:12, j'ai
print unless $h{$_};
est plus efficace et préserve l'ordre.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas
précisé ce qu'il faut faire lorsque une ligne apparaît par exemple
deux fois dans A et une fois dans B. Pour garder le même comportement :
print if (++$h{$_} > 0);
Oubliez cette remarque, le -u de sort précise ce qu'il veut en faire.
Ceci dit c'est une bonne remarque, car dans un premier temps je n'avais pas
envisagé le fait que A puisse contenir des doublons, donc pas mis le -u, et
eu bien des surprises...
Le (on) samedi 24 novembre 2007 11:24, Benoit Izac a écrit (wrote) :
Dans le message , le 24/11/2007 à 11:12, j'ai
print unless $h{$_};
est plus efficace et préserve l'ordre.
Absolument. Le problème c'est que dans la demande de l'OP, il n'est pas précisé ce qu'il faut faire lorsque une ligne apparaît par exemple deux fois dans A et une fois dans B. Pour garder le même comportement :
print if (++$h{$_} > 0);
Oubliez cette remarque, le -u de sort précise ce qu'il veut en faire.
Ceci dit c'est une bonne remarque, car dans un premier temps je n'avais pas
envisagé le fait que A puisse contenir des doublons, donc pas mis le -u, et eu bien des surprises...
Manuel.
mpg
Le (on) samedi 24 novembre 2007 10:42, Nicolas George a écrit (wrote) :
grep -Fxf B A
Waouh. J'adore grep. Merci !
Ceci dit, comme dans la pratique (mais je ne l'ai pas précisé, j'ai eu tort), j'applique en fait un coup de sed à chacun des fichiers (justement pour les mettre sous la forme un mot par ligne), les autres réponses utilisant <(...) me seront quand même bien utiles.
Manuel.
Le (on) samedi 24 novembre 2007 10:42, Nicolas George a écrit (wrote) :
grep -Fxf B A
Waouh. J'adore grep. Merci !
Ceci dit, comme dans la pratique (mais je ne l'ai pas précisé, j'ai eu
tort), j'applique en fait un coup de sed à chacun des fichiers (justement
pour les mettre sous la forme un mot par ligne), les autres réponses
utilisant <(...) me seront quand même bien utiles.
Le (on) samedi 24 novembre 2007 10:42, Nicolas George a écrit (wrote) :
grep -Fxf B A
Waouh. J'adore grep. Merci !
Ceci dit, comme dans la pratique (mais je ne l'ai pas précisé, j'ai eu tort), j'applique en fait un coup de sed à chacun des fichiers (justement pour les mettre sous la forme un mot par ligne), les autres réponses utilisant <(...) me seront quand même bien utiles.