138 lines
3.6 KiB
Awk
138 lines
3.6 KiB
Awk
# cut.awk --- implement cut in awk
|
|
#
|
|
# Arnold Robbins, arnold@skeeve.com, Public Domain
|
|
# May 1993
|
|
|
|
# Options:
|
|
# -c list Cut characters
|
|
# -f list Cut fields
|
|
# -d c Field delimiter character
|
|
#
|
|
# -s Suppress lines without the delimiter
|
|
#
|
|
# Requires getopt() and join() library functions
|
|
|
|
function usage()
|
|
{
|
|
print("usage: cut [-f list] [-d c] [-s] [files...]") > "/dev/stderr"
|
|
print(" cut [-c list] [files...]") > "/dev/stderr"
|
|
exit 1
|
|
}
|
|
BEGIN {
|
|
FS = "\t" # default
|
|
OFS = FS
|
|
while ((c = getopt(ARGC, ARGV, "sf:c:d:")) != -1) {
|
|
if (c == "f") {
|
|
by_fields = 1
|
|
fieldlist = Optarg
|
|
} else if (c == "c") {
|
|
by_chars = 1
|
|
fieldlist = Optarg
|
|
OFS = ""
|
|
} else if (c == "d") {
|
|
if (length(Optarg) > 1) {
|
|
printf("cut: using first character of %s" \
|
|
" for delimiter\n", Optarg) > "/dev/stderr"
|
|
Optarg = substr(Optarg, 1, 1)
|
|
}
|
|
fs = FS = Optarg
|
|
OFS = FS
|
|
if (FS == " ") # defeat awk semantics
|
|
FS = "[ ]"
|
|
} else if (c == "s")
|
|
suppress = 1
|
|
else
|
|
usage()
|
|
}
|
|
|
|
# Clear out options
|
|
for (i = 1; i < Optind; i++)
|
|
ARGV[i] = ""
|
|
if (by_fields && by_chars)
|
|
usage()
|
|
|
|
if (by_fields == 0 && by_chars == 0)
|
|
by_fields = 1 # default
|
|
|
|
if (fieldlist == "") {
|
|
print "cut: needs list for -c or -f" > "/dev/stderr"
|
|
exit 1
|
|
}
|
|
|
|
if (by_fields)
|
|
set_fieldlist()
|
|
else
|
|
set_charlist()
|
|
}
|
|
function set_fieldlist( n, m, i, j, k, f, g)
|
|
{
|
|
n = split(fieldlist, f, ",")
|
|
j = 1 # index in flist
|
|
for (i = 1; i <= n; i++) {
|
|
if (index(f[i], "-") != 0) { # a range
|
|
m = split(f[i], g, "-")
|
|
if (m != 2 || g[1] >= g[2]) {
|
|
printf("cut: bad field list: %s\n",
|
|
f[i]) > "/dev/stderr"
|
|
exit 1
|
|
}
|
|
for (k = g[1]; k <= g[2]; k++)
|
|
flist[j++] = k
|
|
} else
|
|
flist[j++] = f[i]
|
|
}
|
|
nfields = j - 1
|
|
}
|
|
function set_charlist( field, i, j, f, g, n, m, t,
|
|
filler, last, len)
|
|
{
|
|
field = 1 # count total fields
|
|
n = split(fieldlist, f, ",")
|
|
j = 1 # index in flist
|
|
for (i = 1; i <= n; i++) {
|
|
if (index(f[i], "-") != 0) { # range
|
|
m = split(f[i], g, "-")
|
|
if (m != 2 || g[1] >= g[2]) {
|
|
printf("cut: bad character list: %s\n",
|
|
f[i]) > "/dev/stderr"
|
|
exit 1
|
|
}
|
|
len = g[2] - g[1] + 1
|
|
if (g[1] > 1) # compute length of filler
|
|
filler = g[1] - last - 1
|
|
else
|
|
filler = 0
|
|
if (filler)
|
|
t[field++] = filler
|
|
t[field++] = len # length of field
|
|
last = g[2]
|
|
flist[j++] = field - 1
|
|
} else {
|
|
if (f[i] > 1)
|
|
filler = f[i] - last - 1
|
|
else
|
|
filler = 0
|
|
if (filler)
|
|
t[field++] = filler
|
|
t[field++] = 1
|
|
last = f[i]
|
|
flist[j++] = field - 1
|
|
}
|
|
}
|
|
FIELDWIDTHS = join(t, 1, field - 1)
|
|
nfields = j - 1
|
|
}
|
|
{
|
|
if (by_fields && suppress && index($0, fs) == 0)
|
|
next
|
|
|
|
for (i = 1; i <= nfields; i++) {
|
|
if ($flist[i] != "") {
|
|
printf "%s", $flist[i]
|
|
if (i < nfields && $flist[i+1] != "")
|
|
printf "%s", OFS
|
|
}
|
|
}
|
|
print ""
|
|
}
|