Skip to content

Commit

Permalink
Add unlines
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchpaulus committed Nov 18, 2024
1 parent 8a73668 commit 1b1fad0
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 12 deletions.
114 changes: 107 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,113 @@ Best way to understand purpose and syntax of `mshell` is to see it in action. He

*Better Awk One-liners*. Examples from the `awk` book, translated to `mshell`

| Objective | `awk` | `mshell` |
|-----------|-------|----------|
| Print the total number of input lines | `END { print NR }` | `.. len wl` |
| Print the 10th input line | `NR == 10` | `.. :10: wl` (Failure if < 10 lines) |
| Print the last field of every input line | `{ print $NF }` | `.. (ws split :-1: wl) each` |
| Print the last field of the last input line | `{ field = $NF } END { print field }` | `.. :-1: (ws split :-1: wl)` |
| Print every input line with more than four fields | `NF > 4` | `.. dup (ws split) map (len 4 >) filter (" " join) map unlines w` |
```sh
# 1. Print the total nubmer of input lines:
# END { print NR }
.. len wl

# 2. Print the 10th input line:
# NR == 10
.. :10: wl

# 3. Print the last field of every input line:
# { print $NF }
.. (ws split :-1: wl) each

# 4. Print the last field of the last input line:
# { field = $NF }
# END { print field }
.. :-1: " " split :-1: wl

# 5. Print every input line with more than four fields
# NF > 4
.. (dup ws split len [(4 >) (wl) (drop)] if) each

# 6. Print every input line in which the last field is more than 4
# $NF > 4
.. (ws split) map (:-1: toFloat 4 >) filter unlines wl

# 7. Print the total number of fields in all input lines
# { nf = nf + $NF }
# END { print nf }
.. (ws split len) map sum wl

# 8. Print the total number of lines that contain 'Beth'
# /Beth/ { nlines = nlines + 1 }
# END { print nlines }
.. ("Beth" in) filter len wl

# 9. Print the largest first field and the line that contains it (assumes some $1 is positive):
# $1 > max { max = $1; line = $0 }
# END { print max, line }

0 @max
..
# line first
(dup " " split :1: toFloat [(dup max! >) (@max @line)] if)
each max! w " " w line! w

# 10. Print every line that has at least one field
# NF > 0
.. (len 0 >) filter (wl) each

# 11. Print every line longer than 80 characters
# length($0) > 80
.. (len 80 >) filter (wl) each

# 12. Print the number of fields in every line followed by the line itself
# { print NF, $0 }
.. (dup " " split len w " " w wl) each

# 13. Print the first two fields in opposite order, of every line
# { print $2, $1 }
.. (" " split :1: :2: w w) each

# 14. Exchange the first two fields of every line and then print the line
# { temp = $1; $1 = $2; $2 = temp; print }
# Need a way to write value into an index.
# .. (dup " " split :1: :2: swap w w) each

# 15. Print every line with the first field replaced by the line number
# { $1 = NR; print }
# Need a way to write value into an index.
# .. (dup w 1 w w) each

# 16. Print every line after erasing the second field
# { $2 = ""; print }
# Need a way to delete at an index.

# 17. Print in reverse order the fields of every line
# { for (i = NF; i > 0; i = i - 1) printf "%s ", $i
# printf "\n"
# }
.. (" " split reverse " " join wl) each

# 18. Print the sums of the fields of every line
# { sum = 0
# for (i = 1; i <= NF; i = i + 1) sum = sum + $i
# print sum
# }
.. (" " split (toFloat) map sum wl) each

# 19. Add up all fields in all lines and print the sum
# { for (i = 1; i <= NF; i = i + 1) sum = sum + $i }
# END { print sum }
.. (" " split (toFloat) map sum) map sum wl

# 20. Print every line after replacing each field by its absolute value
# { for (i = 1; i <= NF; i = i + 1) $i = ($i < 0) ? -$i : $i; print }
.. (" " split (toFloat abs) map " " join wl) each

```

<!-- | Objective | `awk` | `mshell` | -->
<!-- |-----------|-------|----------| -->
<!-- | Print the total number of input lines | `END { print NR }` | `.. len wl` | -->
<!-- | Print the 10th input line | `NR == 10` | `.. :10: wl` (Failure if < 10 lines) | -->
<!-- | Print the last field of every input line | `{ print $NF }` | `.. (ws split :-1: wl) each` | -->
<!-- | Print the last field of the last input line | `{ field = $NF } END { print field }` | `.. :-1: (ws split :-1: wl)` | -->
<!-- | Print every input line with more than four fields | `NF > 4` | `.. (dup ws split len [(4 >) (wl) (drop)] if) each` | -->


*Simpler execution of common shell idioms*
Expand Down
8 changes: 4 additions & 4 deletions examples/awk.msh
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

# 1. Print the total nubmer of input lines:
# END { print NR }
stdin lines len wl
.. len wl

# 2. Print the 10th input line:
# NR == 10
stdin lines :10: wl
.. :10: wl

# 3. Print the last field of every input line:
# { print $NF }
stdin lines (" " split :-1: wl) each
.. (" " split :-1: wl) each

# 4. Print the last field of the last input line:
# { field = $NF }
Expand All @@ -19,7 +19,7 @@ stdin lines :-1: " " split :-1: wl

# 5. Print every input line with more than four fields
# NF > 4
stdin lines (" " split) map (len 4 >) filter unlines wl
.. (dup " " split len [(4 >) (wl) (drop)] if) each

# 6. Print every input line in which the last field is more than 4
# $NF > 4
Expand Down
13 changes: 12 additions & 1 deletion lib/std.msh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Standard library for mshell

# each (list quote --)
# each (list quote: (item --) --)
def each
over len each-len! # Get total length
0 each-idx! # index
Expand Down Expand Up @@ -60,6 +60,17 @@ def .. stdin lines end
# tt = Tab separated Table (-- list[list[str]])
def tt stdin lines (" " split) map end

# unlines (list[str] -- str)
def unlines
[] unlines-accum! # Accumulator
(
@unlines-accum append
"\n" append
drop
) each
@unlines-accum "" join
end

# map (list quote -- list)
# [seq 1 1000]o; ("Line #" over str + wl) each
# [1 2 3] (2 +) map .s
Binary file modified mshell/mshell
Binary file not shown.
1 change: 1 addition & 0 deletions tests/unlines.msh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["a" "b" "c" "d"] unlines w
4 changes: 4 additions & 0 deletions tests/unlines.msh.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a
b
c
d

0 comments on commit 1b1fad0

Please sign in to comment.