Skip to content

Commit

Permalink
Add support for multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
mohd-akram committed Jan 6, 2024
1 parent 85d7a02 commit 9bf1908
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 23 deletions.
31 changes: 22 additions & 9 deletions jawk
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set -eu
name=`basename $0`

usage() {
echo "usage: $name [-v var=value] [-f progfile | 'prog'] [file]" >&2
echo >&2 "usage: $name [-v var=value] [-f progfile | 'prog'] [file ...]"
exit 1
}

Expand All @@ -22,7 +22,7 @@ done
i=0
skip=
f=
file=
files=
for arg do
i=$((i+1))
shift
Expand All @@ -34,19 +34,26 @@ for arg do
fi
else
if [ ! "$p" ]; then prog=$arg; p=1
elif [ ! "$f" ]; then file=$arg; f=1
else usage; fi
else
if [ ! "$f" ]; then files="$arg"
else files=$(printf '%s\t%s' "$files" "$arg"); fi
f=$((f+1));
fi
continue
fi
set -- "$@" "$arg"
done

if [ ! "$p" ]; then usage; fi
if [ ! "$f" ]; then file=-; fi
if [ ! "$f" ]; then files=-; fi

jawk='
BEGIN { JSON="\1"; TYPE="\2"; __KEYS="\3"; FS="\n"; __jawk__init() }
{ __parse_value($0); $0 = _[JSON]; NR = ++__NR; FILENAME = __FILENAME }
BEGIN {
ARGC=__ARGC=split(__ARGV, ARGV, "\t"); RS=FS="\n"
JSON="\1"; TYPE="\2"; __KEYS="\3"; __jawk__init()
}
/^---/ { FILENAME=substr($0, 4); __FNR=0; next }
{ ARGC=__ARGC; RS=FS="\n"; __parse_value($0); $0=_[JSON]; NR=++__NR; FNR=++__FNR }
function __jawk__init(i) {
__CHAR[0] = "\0"; __CHAR[1] = "\1"; __CHAR[2] = "\2"
Expand Down Expand Up @@ -306,9 +313,15 @@ STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
KEYWORD='null|false|true'
SPACE='[[:space:]]+'
JSON="$STRING|$NUMBER|$KEYWORD|[][{}:,]"

: ${AWK=$(command -v gawk || echo awk)}
: ${EGREP=$(command -v ugrep || echo 'grep -E')}

$EGREP -o "$STRING|$NUMBER|$KEYWORD|[][{}:,]" "$file" |
$AWK -v __FILENAME="$file" "$@" "$jawk$prog"
IFS=$(printf '\t')
for file in $files; do
printf -- '---%s\n' "$file"
$EGREP -o "$JSON" "$file" 2>/dev/null
done | $AWK -v __ARGV="$files" "$@" "$jawk$prog
BEGIN { ARGC=1; RS=FS=\"\n\" }
"
8 changes: 6 additions & 2 deletions src/jawk.awk
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
BEGIN { JSON="\1"; TYPE="\2"; __KEYS="\3"; FS="\n"; __jawk__init() }
{ __parse_value($0); $0 = _[JSON]; NR = ++__NR; FILENAME = __FILENAME }
BEGIN {
ARGC=__ARGC=split(__ARGV, ARGV, "\t"); RS=FS="\n"
JSON="\1"; TYPE="\2"; __KEYS="\3"; __jawk__init()
}
/^---/ { FILENAME=substr($0, 4); __FNR=0; next }
{ ARGC=__ARGC; RS=FS="\n"; __parse_value($0); $0=_[JSON]; NR=++__NR; FNR=++__FNR }

function __jawk__init(i) {
__CHAR[0] = "\0"; __CHAR[1] = "\1"; __CHAR[2] = "\2"
Expand Down
23 changes: 16 additions & 7 deletions src/jawk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set -eu
name=`basename $0`

usage() {
echo "usage: $name [-v var=value] [-f progfile | 'prog'] [file]" >&2
echo >&2 "usage: $name [-v var=value] [-f progfile | 'prog'] [file ...]"
exit 1
}

Expand All @@ -22,7 +22,7 @@ done
i=0
skip=
f=
file=
files=
for arg do
i=$((i+1))
shift
Expand All @@ -37,15 +37,18 @@ for arg do
# Get prog and file
else
if [ ! "$p" ]; then prog=$arg; p=1
elif [ ! "$f" ]; then file=$arg; f=1
else usage; fi
else
if [ ! "$f" ]; then files="$arg"
else files=$(printf '%s\t%s' "$files" "$arg"); fi
f=$((f+1));
fi
continue
fi
set -- "$@" "$arg"
done

if [ ! "$p" ]; then usage; fi
if [ ! "$f" ]; then file=-; fi
if [ ! "$f" ]; then files=-; fi

jawk=$(cat jawk.awk)

Expand All @@ -55,9 +58,15 @@ STRING="\"$CHAR*($ESCAPE$CHAR*)*\""
NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
KEYWORD='null|false|true'
SPACE='[[:space:]]+'
JSON="$STRING|$NUMBER|$KEYWORD|[][{}:,]"

: ${AWK=$(command -v gawk || echo awk)}
: ${EGREP=$(command -v ugrep || echo 'grep -E')}

$EGREP -o "$STRING|$NUMBER|$KEYWORD|[][{}:,]" "$file" |
$AWK -v __FILENAME="$file" "$@" "$jawk$prog"
IFS=$(printf '\t')
for file in $files; do
printf -- '---%s\n' "$file"
$EGREP -o "$JSON" "$file" 2>/dev/null
done | $AWK -v __ARGV="$files" "$@" "$jawk$prog
BEGIN { ARGC=1; RS=FS=\"\n\" }
"
20 changes: 15 additions & 5 deletions test/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,21 @@ test "trailing space in JSON"
out=$(printf '{"a":1, \n"b":2}' | jawk '{print _["b"]}')
[ "$out" = '2' ]

test "file"
echo '{"age":10}' >test/test.json
out=$(jawk '{print FILENAME;print _["age"]}' test/test.json; rm test/test.json)
[ "$out" = "$(printf 'test/test.json\n10')" ]

test "NR"
out=$(printf '{\n"age":10\n}\n{\n"age":12\n}' | jawk '{print NR}')
[ "$out" = "$(printf '1\n2')" ]

test "files"
printf '{"age":10}\n{"age":20}' >test/test.json
printf '{"age":30}\n{"age":40}' >test/test2.json
out=$(jawk \
'BEGIN{print ARGC,ARGV[1],ARGV[2]}{print ARGC,FILENAME,NR,FNR,_["age"]}' \
test/test.json test/test2.json
rm test/test*.json
)
[ "$out" = "$(printf '%s\n' \
'2 test/test.json test/test2.json' \
'2 test/test.json 1 1 10' \
'2 test/test.json 2 2 20' \
'2 test/test2.json 3 1 30' \
'2 test/test2.json 4 2 40')" ]

0 comments on commit 9bf1908

Please sign in to comment.