Skip to content

Commit

Permalink
Merge pull request #22 from clue-labs/tsv
Browse files Browse the repository at this point in the history
Add reference to TSV (Tab-Separated Values)
  • Loading branch information
clue authored Dec 28, 2020
2 parents 8b98da2 + d829b68 commit 4ce22ea
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ to process newline-delimited JSON (NDJSON) files (`.ndjson` file extension).
{"name":"Bob","age":50,"comment":"Hello\nWorld!"}
```

As another alternative, if you want to use a CSV-variant that avoids some of its
shortcomings (and is somewhat faster!), you may want to use [clue/reactphp-tsv](https://github.com/clue/reactphp-tsv)
to process Tab-Separated-Values (TSV) files (`.tsv` file extension).

```tsv
name age comment
Alice 30 Yes, I like cheese
Bob 50 Hello world!
```

## Usage

### Decoder
Expand Down Expand Up @@ -407,6 +417,10 @@ This project is released under the permissive [MIT license](LICENSE).
you may want to use [clue/reactphp-ndjson](https://github.com/clue/reactphp-ndjson)
to process newline-delimited JSON (NDJSON) files (`.ndjson` file extension).

* If you want to process a slightly simpler text-based tabular data format,
you may want to use [clue/reactphp-tsv](https://github.com/clue/reactphp-tsv)
to process Tab-Separated-Values (TSV) files (`.tsv` file extension).

* If you want to process compressed CSV files (`.csv.gz` file extension)
you may want to use [clue/reactphp-zlib](https://github.com/clue/reactphp-zlib)
on the compressed input stream before passing the decompressed stream to the CSV decoder.
Expand Down
1 change: 1 addition & 0 deletions examples/11-csv2ndjson.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

// $ php examples/11-csv2ndjson.php < examples/users.csv > examples/users.ndjson
// see also https://github.com/clue/reactphp-ndjson

use Clue\React\Csv\AssocDecoder;
use React\EventLoop\Factory;
Expand Down
55 changes: 55 additions & 0 deletions examples/12-csv2tsv.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

// $ php examples/12-csv2tsv.php < examples/users.csv > examples/users.tsv
// see also https://github.com/clue/reactphp-tsv

use Clue\React\Csv\Decoder;
use React\EventLoop\Factory;
use React\Stream\ReadableResourceStream;
use React\Stream\WritableResourceStream;
use React\Stream\ThroughStream;

require __DIR__ . '/../vendor/autoload.php';

$loop = Factory::create();

$exit = 0;
$in = new ReadableResourceStream(STDIN, $loop);
$out = new WritableResourceStream(STDOUT, $loop);
$info = new WritableResourceStream(STDERR, $loop);

$delimiter = isset($argv[1]) ? $argv[1] : ',';

$decoder = new Decoder($in, $delimiter);

$encoder = new ThroughStream(function ($data) {
$data = \array_map(function ($value) {
return \addcslashes($value, "\0..\37");
}, $data);

return \implode("\t", $data) . "\n";
});

$decoder->pipe($encoder)->pipe($out);

$decoder->on('error', function (Exception $e) use ($info, &$exit) {
$info->write('ERROR: ' . $e->getMessage() . PHP_EOL);
$exit = 1;
});

// TSV files MUST include a header line, so complain if CSV input ends without a single line
$decoder->on('end', $empty = function () use ($info, &$exit) {
$info->write('ERROR: Empty CSV input' . PHP_EOL);
$exit = 1;
});
$decoder->once('data', function () use ($decoder, $empty) {
$decoder->removeListener('end', $empty);
});

$info->write('You can pipe/write a valid CSV stream to STDIN' . PHP_EOL);
$info->write('Valid TSV (Tab-Separated Values) will be forwarded to STDOUT' . PHP_EOL);
$info->write('Invalid CSV will raise an error on STDERR and exit with code 1' . PHP_EOL);

$loop->run();

exit($exit);

0 comments on commit 4ce22ea

Please sign in to comment.