Posting this entry so that awk newbies will see the use of awk NF,NR variables along with some basic awk 'for' and 'if constructs' use.
Input file:
$ cat file.txt
-5232,-92338,84545,34
-2233,25644,23233,2
6211,-1212,4343,43
-2434,621171,9121,-33
Required: Extract the numbers which starts with '-'
Solution using bash tr (command to translate or delete characters)
$ tr ',' '\n' < file.txt | grep ^-
Output:
-5232
-92338
-2233
-1212
-2434
-33
Using awk:
$ awk -F "," '
{for(i=1; i<=NF;i++)
if($i ~ /^-/) {printf "%s\n",$i}
}
' file.txt
Extending the above one liner to print the line number and field number where the negative value is present.
$ awk -F "," '
{for(i=1; i<=NF;i++)
if($i ~ /^-/) {
printf "Line # %s,Field # %s,Value = %s\n",NR,i,$i
}
}' file.txt
Output:
Line # 1,Field # 1,Value = -5232
Line # 1,Field # 2,Value = -92338
Line # 2,Field # 1,Value = -2233
Line # 3,Field # 2,Value = -1212
Line # 4,Field # 1,Value = -2434
Line # 4,Field # 4,Value = -33
Related posts:
- Awk for loop
- Awk if else
- Awk variables
6 comments:
Alternate RS :)
awk 'BEGIN {RS=",|\n"}/^-/ {print}' file.txt
@Voyeg3r, thank you so much, its a good one.
sed -e '
/,/y/,/\n/
/^[-]/P
D
'
set -f
set -- $(< file.txt tr ',-' ' _')
dc -e "
# register 'a' prints TOS
[p]sa
# decrement function in register 'm'
[1 -]sm
# register 'c' pushes TOS into register 'r'
[Sr z 1 !>c]sc
# register 'd' pops register 'r' & prints if it is negative
[Lrd0>asx lklmxsk lk 1 !>d]sd
# starting stack state
$*
# store the stack length in register k
zsk
# pop off from stack & push into register r
lcx
## loop while register k >= 1
ldx
"
if='file.txt'
< $if tr ',-' ' _' |
dc -e "
[q]sq
[Srlk1+sk[]]sN
[d0>Ns0z0<A]sA
[Lrps0lk1-dsk0<P]sP
[?z0=q0sklAxlPxl?x]s?
l?x
"
Task: Print the line number and field number also where the negative value is present.
if='file.txt'
# "tr" converts the CSV-numbers to space-separated and also
# "dc" takes negative numbers as starting with "_" rather than "-"
< $if tr ',-' '\040_' \
dc -e "
[q]sq
# store the field number and corresp. negative number onto stack 'M'
[z SM SM []]sN
# recursive macro that picks up the negative numbers from the current line
[d 0 >N s0 z 0<A]sA
# the printing macro in the desired format
[ [line #]n l.n [, Field #]n n [, Value = ]n pc ]sP
# grab a pair (field num and negative num) from the stack 'M'
# then invoke the printing macro 'P' on the pair.
# then check by looking nondestructively at the TOS of 'M'
# whether we've reached the end. If not,
# recursively call itself for the next pair...
[LMLM lPx lM 0 !=B]sB
[? z 0 =q # grab next line & quit if found empty else do the below
l.1+s. # adjust line num counter
0SM # stuff stack ending number
lAx # grab all -ve nums on the current line
lBx # print all -ve nums on the current line in the approp. fmt.
l?x # rinse & recursively repeat...
]s?
# initialize line number counter '.'
0s.
# *** lights camera action! ***
l?x
"
Post a Comment