Re: a one-liner for this trivial problem?
by CountOrlok (Friar) on Apr 16, 2013 at 14:52 UTC
|
grep can do this for you: grep -v -f small_file big_file | [reply] [d/l] |
|
|
| [reply] |
Re: a one-liner for this trivial problem?
by hdb (Monsignor) on Apr 16, 2013 at 14:46 UTC
|
You do it the other way round: first you read the smaller file into a hash. Then you open the bigger file, check for each ID if it exists in the hash and only print if it does not.
| [reply] [d/l] |
|
|
Yeah, true, I was just hoping there could be an one-liner solution to this, and not need to write a "normal" script...
| [reply] |
|
|
You can do that in one line. The easiest way is to use a really long line and to fill that line by removing all line breaks from the script.
Maybe you can show us the code you've already written to solve the problem. Then we can help you with the technical hurdles that might prevent that code from working as a one-liner.
| [reply] |
|
|
Re: a one-liner for this trivial problem?
by kcott (Archbishop) on Apr 16, 2013 at 17:37 UTC
|
$ cat 1028930_short
2
5
6
8
$ cat 1028930_long
1
2
3
4
5
6
7
8
9
$ perl -i -nE 'chomp; if ($s) { $d{$_} or say } else { ++$d{$_}; ++$s
+if eof; say }' 1028930_short 1028930_long
$ cat 1028930_short
2
5
6
8
$ cat 1028930_long
1
3
4
7
9
| [reply] [d/l] [select] |
Re: a one-liner for this trivial problem?
by space_monk (Chaplain) on Apr 16, 2013 at 17:09 UTC
|
perl -pie '
BEGIN {
open $fh, "<" , "littlefile" or die "Cannot read file";
our %hash = map { $_ => 1} <$fh>;
}
print if not $hash{$_};
' < bigfile
All the above will go on one line. any minor bugs are your problem (chomps may be needed for example) :-)
A Monk aims to give answers to those who have none, and to learn from those who know more.
| [reply] [d/l] |
Re: a one-liner for this trivial problem?
by NetWallah (Canon) on Apr 16, 2013 at 23:35 UTC
|
perl -ne "$small||=$ARGV; $small eq $ARGV? $h{$_}++: $h{$_}?0:print" s
+mall.txt large.txt
This takes advantage of the fact that $ARGV contains the file name.
Use single-quotes if you run in *nix.
"I'm fairly sure if they took porn off the Internet, there'd only be one website left, and it'd be called 'Bring Back the Porn!'"
-- Dr. Cox, Scrubs
| [reply] [d/l] |
|
|
perl -ne "
$ARGV eq $ARGV[0] ?
$h{$_}++ :
$h{$_} ? 0 : print;
" small.txt large.txt
A Monk aims to give answers to those who have none, and to learn from those who know more.
| [reply] [d/l] |
Re: a one-liner for this trivial problem?
by jakeease (Friar) on Apr 17, 2013 at 08:32 UTC
|
#!/usr/bin/perl -w
use strict;
sub slurp {
my $file = shift;
open my $fh, '<', $file or return undef;
local $/ unless wantarray;
return <$fh>;
}
my @long = slurp 'long';
my @short = slurp 'short';
my %diff;
@diff {@long} = ();
delete @diff {@short};
my @diff = sort keys %diff;
print "@diff\n";
| [reply] [d/l] |
Re: a one-liner for this trivial problem?
by PrakashK (Pilgrim) on Apr 19, 2013 at 19:11 UTC
|
perl -ne 'BEGIN {open my $sh, "<", shift; %h = map {$_ => 1} <$sh>} print unless $h{$_}' small large
Read the small file in the BEGIN block and shift it out of @ARGV.
A minor plus of this approach is that any number of "large" files can be passed, after the "small" file.
If you have File::Slurp available:
perl -MFile::Slurp=slurp -ne 'BEGIN {%h = map {$_ => 1} slurp shift} print unless $h{$_}' small large
| [reply] [d/l] [select] |
|
|
exclude smallfile from largefile
grep -i -v -f smallfile largefile
include only smallfile from largefile
grep -i -f smallfile largefile
include only smallfile from largefile in reverse order numberic by kolumn 2
grep -i -f smallfile largefile | sort -r -b -g -k 2
| [reply] [d/l] [select] |