Skip to content

Commit 4ce22ea

Browse files
authored
Merge pull request #22 from clue-labs/tsv
Add reference to TSV (Tab-Separated Values)
2 parents 8b98da2 + d829b68 commit 4ce22ea

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ to process newline-delimited JSON (NDJSON) files (`.ndjson` file extension).
128128
{"name":"Bob","age":50,"comment":"Hello\nWorld!"}
129129
```
130130

131+
As another alternative, if you want to use a CSV-variant that avoids some of its
132+
shortcomings (and is somewhat faster!), you may want to use [clue/reactphp-tsv](https://github.com/clue/reactphp-tsv)
133+
to process Tab-Separated-Values (TSV) files (`.tsv` file extension).
134+
135+
```tsv
136+
name age comment
137+
Alice 30 Yes, I like cheese
138+
Bob 50 Hello world!
139+
```
140+
131141
## Usage
132142

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

420+
* If you want to process a slightly simpler text-based tabular data format,
421+
you may want to use [clue/reactphp-tsv](https://github.com/clue/reactphp-tsv)
422+
to process Tab-Separated-Values (TSV) files (`.tsv` file extension).
423+
410424
* If you want to process compressed CSV files (`.csv.gz` file extension)
411425
you may want to use [clue/reactphp-zlib](https://github.com/clue/reactphp-zlib)
412426
on the compressed input stream before passing the decompressed stream to the CSV decoder.

examples/11-csv2ndjson.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

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

56
use Clue\React\Csv\AssocDecoder;
67
use React\EventLoop\Factory;

examples/12-csv2tsv.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
// $ php examples/12-csv2tsv.php < examples/users.csv > examples/users.tsv
4+
// see also https://github.com/clue/reactphp-tsv
5+
6+
use Clue\React\Csv\Decoder;
7+
use React\EventLoop\Factory;
8+
use React\Stream\ReadableResourceStream;
9+
use React\Stream\WritableResourceStream;
10+
use React\Stream\ThroughStream;
11+
12+
require __DIR__ . '/../vendor/autoload.php';
13+
14+
$loop = Factory::create();
15+
16+
$exit = 0;
17+
$in = new ReadableResourceStream(STDIN, $loop);
18+
$out = new WritableResourceStream(STDOUT, $loop);
19+
$info = new WritableResourceStream(STDERR, $loop);
20+
21+
$delimiter = isset($argv[1]) ? $argv[1] : ',';
22+
23+
$decoder = new Decoder($in, $delimiter);
24+
25+
$encoder = new ThroughStream(function ($data) {
26+
$data = \array_map(function ($value) {
27+
return \addcslashes($value, "\0..\37");
28+
}, $data);
29+
30+
return \implode("\t", $data) . "\n";
31+
});
32+
33+
$decoder->pipe($encoder)->pipe($out);
34+
35+
$decoder->on('error', function (Exception $e) use ($info, &$exit) {
36+
$info->write('ERROR: ' . $e->getMessage() . PHP_EOL);
37+
$exit = 1;
38+
});
39+
40+
// TSV files MUST include a header line, so complain if CSV input ends without a single line
41+
$decoder->on('end', $empty = function () use ($info, &$exit) {
42+
$info->write('ERROR: Empty CSV input' . PHP_EOL);
43+
$exit = 1;
44+
});
45+
$decoder->once('data', function () use ($decoder, $empty) {
46+
$decoder->removeListener('end', $empty);
47+
});
48+
49+
$info->write('You can pipe/write a valid CSV stream to STDIN' . PHP_EOL);
50+
$info->write('Valid TSV (Tab-Separated Values) will be forwarded to STDOUT' . PHP_EOL);
51+
$info->write('Invalid CSV will raise an error on STDERR and exit with code 1' . PHP_EOL);
52+
53+
$loop->run();
54+
55+
exit($exit);

0 commit comments

Comments
 (0)