Table of contents
- Preface
- Synopsis
- Notation
- For First fsed
- For Second fsed
- Challenge
- Task for first language
- Task for second language
- Input restrictions
- Other rules
- Test cases
- Further readings
- Sample implementation for second task
Preface
As a (formerly) serious shell(script) enthusiast I know two useful utilities:
- fsed utility, developed by ShellShoccar-jpn
- fsed utility, developed by Universal Shell Programming Lab as a part of Open-usp-Tukubai (also known as Unicage tools)
They have incompatible synopsis.
Synopsis
Notation
(0) I am using utility synopsis syntax, which is represented by space-delimined list of strings, to describe their specifications:
(0-1) part surrounded by the braces means it is optional part, and
(0-2) the pipe | inside the braces means that one of two items on both sides of the pipe can be used but not both, and
(0-3) the ellipsis ... means that the part can be repeated one or more times.
For First fsed
(1) The usage of former utility is:
fsed pattern replacement [file...]
where
- (1-1)
patternis a nonempty string consists of any characts except newline, and - (1-2)
replacementis any string, and - (1-3)
file, which can occur for zero or more times, is any string.
For Second fsed
(2) The latter usage is:
fsed [-e|-i] s-command [file]
fsed [[-e|-i] s-command ...] -e s-command [file]
fsed [[-e|-i] s-command ...] -i s-command [file]
fsed [[-e|-i] s-command ...] s-command file
where
- (2-1)
-eor-ioption, (2-1-2) which can be used exclusively but not both at same time, applies to each followings-command, and - (2-2)
file, (2-2-1) either (2-2-1a) a hyphen-or (2-2-1b) a string who starts with a character other than hyphen, (2-2-2) must be specified explicitly when in case of fourth usage: (2-2-3a) multiples-commands are specified and (2-2-3b) the lasts-commandhas no-eor-ioptions.
(2-3) The s-command looks like these:
s/pattern/replacement/
s,/,-,42
s/New York/California/g
(2-3-1) The s-command is a list of four strings delimited by a character;
- (2-3-2) the first part must be the letter
s, and - (2-3-3) the second and third parts are any strings except they cannot contain the delimiter character specified by (2-3-1), and
- (2-3-4) the fourth and last part is either
- (2-3-4a) empty, or
- (2-3-4b) a decimal representation of a positive integer, or
- (2-3-4c) the letter
g.
Challenge
Write a polyglot in two languages of your choice to solve different tasks for each language.
Task for first language
Given a list of strings (which is arguments for the first fsed utility), decide whether it meets its usage. I.e. return true if input meets all conditions as follows, and return false otherwise:
- has two or more items,
- first item has one or more characters, and
- first item has no newlines.
Task for second language
Similar to previous task for second fsed.
Input restrictions
Input strings shall be newlines and characters of ASCII printables except backslash \.
Other rules
decision-problem. Standard I/O. Standard loopholes. code-golf.
Test cases
Line-by-line. Like JSON or Python syntax.
Falsey for first task
[]
[""]
["",""]
["","",""]
["\n","","-","bar"]
["foo\nbar","baz\nbaz","foo"]
Truthy for first task
["foo",""]
["foo","bar","-","--help"]
["foo bar","baz\nbaz","quux"]
["F","","","",""]
Falsey for second task
[]
["foo"]
["s\nAmerica\nCanada\n3","Singapore.txt","Jamaica.mp3"]
["s(p)(q)(9","-e"]
["s"]
["s/"]
["s/foo"]
["s/foo/bar"]
["S!foo!bar!"]
["s!foo!bar!0","file.lol"]
["s!foo!bar!-1","file.lol"]
["s!foo!bar!!","file.lol"]
Truthy for second task
["s/foo//"]
["s/foo/bar/"]
["s/foo\nbar/baz/"]
["s\nAmerica\nCanada\n3","Singapore.txt"]
["s/alpha/Alpha/1","s/bravo/Bravo/3","data1.txt"]
["s/foo/FOO/g","data2.txt"]
["-e","s/^[f]oo+$/FOO/","data3.txt"]
["-i","s/intercal/DO.1<-#32/g","data4.txt"]
["s/intercal/DOREADOUT.1/42","-i","s/brainfuck/++++++[->+++++++<]./1","data5.txt"]
["s,///,/ab/bba/Abba,7","data6.txt"]
Further readings
當仲寛哲/山崎裕詞/熊谷章/熊野憲辰/木ノ下勝郎, "ユニケージ原論".
USP研究所, "実践ユニケージ開発手法01 コマンド学習編"
USP研究所, "実践ユニケージ開発手法02 シェルスクリプト学習編"
USP研究所, "実践ユニケージ開発手法03 Webアプリケーション編"
松浦智之, "すべてのUNIXで20年動くプログラムはどう書くべきか デプロイ・保守に苦しむエンジニア達へ贈る[シェルスクリプトレシピ集]"
Sample implementation for second task
In Python 3, 1810 bytes
from typing import List, Tuple
def isUnicageFsed(args: List[str]) -> Tuple[bool, str]:
filename: str = "-"
s_commands: List[Tuple[str, str]] = []
while len(args) > 0:
if args[0].startswith("-") and len(args[0]) > 1:
is_valid_flag = args[0] in "-e", "-i"
if not is_valid_flag:
return (False, f"invalid flag: {args[0]}")
try:
s_commands.append((args[0], args[1]))
except IndexError:
return (False, f"missing s-command for flag {args[0]}")
args = args[2:]
else:
s_commands.append((None, args[0]))
args = args[1:]
if len(s_commands) > 1:
(flag, maybe_filename) = s_commands[-1]
if not flag:
filename = maybe_filename
s_commands.pop()
elif len(s_commands) < 1:
return (False, "missing s-command")
rules: List[Tuple[str, Tuple[str, str, int | str | None]]] = []
for (flag, s_command) in s_commands:
try:
delimiter = s_command[1]
except IndexError:
return (False, f"incomplete s-command: {s_command}")
try:
(s, pat, rep, s_flag) = s_command.split(delimiter, 3)
except ValueError:
return (False, f"incomplete s-command: {s_command}")
if s != "s":
return (False, f"not s-command: {s_command}")
try:
s_flag = int(s_flag)
if s_flag <= 0:
return (False, f"invalid field for s-command: {s_flag}")
except ValueError:
is_flag = not s_flag or s_flag == "g"
if not is_flag:
return (False, f"invalid flag for s-command: {s_flag}")
rules.append((flag, (pat, rep, s_flag)))
return (True, None)
Variable not in scope: inList :: [[Char]] -> p\$\endgroup\$