column -d: Spalten löschen

This commit is contained in:
wkh
2026-10-12 00:10:36 +02:00
parent a9f3c0b255
commit a02e5cb109
7 changed files with 80 additions and 3 deletions
+1
View File
@@ -10,6 +10,7 @@ folgen [Semantic Versioning](https://semver.org/lang/de/). Die Version steht in
## [0.6.0] - 2026-10-11 ## [0.6.0] - 2026-10-11
### Hinzugefügt ### Hinzugefügt
- `column -d Spalte ...` (und `project -d`) löscht Spalten: alle anderen bleiben in ihrer Reihenfolge. Fehler bei unbekannter Spalte oder wenn alle gelöscht würden. Dazu Abschnitt in `man/column.man`, Beispiel in `testall.cmds` und Tests.
- Steuertabellen 2026 für `tax`: `demo/taxDE2026`, `taxAT2026`, `taxCH2026` (nur Bundessteuer), `taxLI2026` (nur Landessteuer), erzeugt mit `tools/gen_tax_tables.rb`, mit Tests. - Steuertabellen 2026 für `tax`: `demo/taxDE2026`, `taxAT2026`, `taxCH2026` (nur Bundessteuer), `taxLI2026` (nur Landessteuer), erzeugt mit `tools/gen_tax_tables.rb`, mit Tests.
### Geändert ### Geändert
+2
View File
@@ -40,6 +40,8 @@ Dasselbe gilt für **Listen** (ein Datensatz als `Spalte<Tab>Wert`-Zeilen, die
Datei beginnt mit einer Leerzeile). `tabletolist` und `listtotable` wandeln um, Datei beginnt mit einer Leerzeile). `tabletolist` und `listtotable` wandeln um,
die meisten Befehle lesen beides. die meisten Befehle lesen beides.
`column -d Spalte ...` löscht Spalten (alle anderen bleiben), `column Spalte ...` wählt sie aus.
`row`, `compute` und `validate` übergeben ihren Ausdruck an awk, nachdem sie `row`, `compute` und `validate` übergeben ihren Ausdruck an awk, nachdem sie
Spaltennamen durch `$N` ersetzt haben. Es gilt also awk-Syntax. Spaltennamen durch `$N` ersetzt haben. Es gilt also awk-Syntax.
+3
View File
@@ -12,6 +12,9 @@ rdb select 'Description ~ /gloves/' < inventory
## column (project): pick columns in any order; a name that does not exist becomes a new empty column ## column (project): pick columns in any order; a name that does not exist becomes a new empty column
column Description Cost < inventory column Description Cost < inventory
project Item Notes < owners project Item Notes < owners
## column -d: keep all columns except the named ones (a deletion)
column -d Cost Value < inventory
subtotal Date Debit Credit < journal | column -d Account Description
## sorttable: -n numeric, -r reverse, -f fold case ## sorttable: -n numeric, -r reverse, -f fold case
sorttable -nr Cost < inventory sorttable -nr Cost < inventory
## compute: calculate columns from other columns (the new column must exist, so make it with addcol) ## compute: calculate columns from other columns (the new column must exist, so make it with addcol)
+17
View File
@@ -28,6 +28,23 @@ Item Notes
1 1
3 3
6 6
## column -d: keep all columns except the named ones (a deletion)
$ column -d Cost Value < inventory
Item Amount Description
---- ------ -----------
1 3 rubber gloves
2 100 test tubes
3 5 clamps
4 23 plates
5 99 cleaning cloth
6 89 bunsen burners
7 5 scales
$ subtotal Date Debit Credit < journal | column -d Account Description
Date Debit Credit
---- ----- ------
861222 25000 25000
861223 10000 10000
861224 30000 30000
## sorttable: -n numeric, -r reverse, -f fold case ## sorttable: -n numeric, -r reverse, -f fold case
$ sorttable -nr Cost < inventory $ sorttable -nr Cost < inventory
Item Amount Cost Value Description Item Amount Cost Value Description
+13 -2
View File
@@ -11,9 +11,20 @@ Rdb.register('row', 'Make a new table where rows match logical condition',
end end
Rdb.alias_for('select', 'row') Rdb.alias_for('select', 'row')
Rdb.register('column', 'Display columns of a table in any order', 'column [ Column ... ] < tableorlist') do |args| Rdb.register('column', 'Display columns of a table in any order', 'column [ -d ] [ Column ... ] < tableorlist') do |args|
drop = args.first == '-d'
args.shift if drop
t = table_in t = table_in
next t.write if args.empty? next t.write if args.empty? && !drop
die 'usage: column -d Column ... < tableorlist' if drop && args.empty?
if drop # keep every column except the named ones
gone = args.map { |a| t.index_of(a) }
keep = t.head.each_index.reject { |i| gone.include?(i) }
die 'column -d would delete every column' if keep.empty?
next t.with(head: keep.map { |i| t.head[i] }, rows: t.rows.map { |r| keep.map { |i| r[i] } }).write
end
idx = args.map { |a| Rdb.column_index(t.head, a) } idx = args.map { |a| Rdb.column_index(t.head, a) }
head = args.each_with_index.map { |a, n| idx[n] ? t.head[idx[n]] : a } head = args.each_with_index.map { |a, n| idx[n] ? t.head[idx[n]] : a }
+18
View File
@@ -129,6 +129,24 @@ Names that are also
reserved words or are followed by reserved words or are followed by
.B ( .B (
are never taken for columns. are never taken for columns.
.SH "Deleting Columns"
.I "(Ruby re-creation only.)"
.DM
column -d Column ... < tableorlist
.DE
.PP
With the option
.BR -d ,
.B column
keeps every column
.I except
those named.
The order of the other columns stays as it is.
It is an error to name a column that does not exist,
or to delete every column.
.DM
subtotal Date Debit Credit < journal | column -d Account Description
.DE
.SH "See Also" .SH "See Also"
.B .B
project, project,
+26 -1
View File
@@ -5,6 +5,31 @@ require 'pty'
require_relative '../lib/rdb' require_relative '../lib/rdb'
class SelectionTest < RdbCase class SelectionTest < RdbCase
def test_column_d_deletes_columns
out = rdb('column', '-d', 'Cost', 'Value', file: 'inventory')
assert_equal %w[Item Amount Description], out.lines.first.chomp.split("\t")
assert_equal %w[1 3 rubber\ gloves], data(out).first
assert_equal %w[Date Debit Credit], rdb('column', '-d', 'Account', 'Description', stdin: rdb('subtotal', 'Date', 'Debit', 'Credit', file: 'journal')).lines.first.chomp.split("\t")
end
def test_column_d_errors
src = File.read(File.join(@dir, 'owners'))
[%w[-d], %w[-d Nope], %w[-d Item Owner]].each do |args|
out, err, st = run3('column', *args, stdin: src)
refute st.success?, "column #{args.join(' ')} should fail"
assert_equal '', out
refute_empty err
end
end
def test_column_d_works_on_lists_and_with_icase
list = rdb('tabletolist', file: 'owners')
assert_includes rdb('column', '-d', 'Item', stdin: list), "Owner\tann"
out, _e, st = run3('column', '-d', 'COST', stdin: File.read(File.join(@dir, 'inventory')), env: { 'RDB_ICASE' => '1' })
assert st.success?
refute_includes out.lines.first, 'Cost'
end
def test_splittable_pieces_and_errors def test_splittable_pieces_and_errors
out, = run3('splittable', '-4', 'inventory') out, = run3('splittable', '-4', 'inventory')
assert_equal 4, data(File.read(File.join(@dir, 'inventoryaa'))).size assert_equal 4, data(File.read(File.join(@dir, 'inventoryaa'))).size
@@ -463,7 +488,7 @@ end
class HelpTest < RdbCase class HelpTest < RdbCase
def test_whatis_whatwill_commands def test_whatis_whatwill_commands
assert_includes rdb('whatis', 'column'), " column - display columns of a table in any order\n column column [ Column ... ] < tableorlist\n" assert_includes rdb('whatis', 'column'), " column - display columns of a table in any order\n column column [ -d ] [ Column ... ] < tableorlist\n"
assert_includes rdb('whatwill', 'total'), 'subtotal' assert_includes rdb('whatwill', 'total'), 'subtotal'
assert_operator data(rdb('commands')).size, :>, 120 assert_operator data(rdb('commands')).size, :>, 120
assert_operator rdb('howmany').to_i, :>, 120 assert_operator rdb('howmany').to_i, :>, 120