sed and awk

Good morning,

Any idea how to repalce this sed or awk?

file:10:no:1011
file:10:file:1011
data:10:say:1011
data:10:data:1011

output:
file:10:yes:1011
file:10:yes:1011
data:10:yes:1011
data:10:yes:1011

Good evening! :slight_smile:

One way...

$ cat data
file:10:no:1011
file:10:file:1011
data:10:say:1011
data:10:data:1011
$ awk -F: -v OFS=: '{$3="yes";print}' data
file:10:yes:1011
file:10:yes:1011
data:10:yes:1011
data:10:yes:1011
$

thanks sir Perderabo, it works in aix, but not in solaris :(. actually it was intended for solaris, but thanks a lot.

Invinzin, on Solaris you may have gawk available.

$ gawk -F: -v OFS=: '{$3="yes";print}' data

thanks i use nawk :slight_smile:

hi sir's,
here's the problem i encountered regarding w/ awk. Hope someone could help. below works for me.

$cat passwdlist
root:6GNlhvGxH3jOk:6445::::::
daemon:asasda:6445::::::
bin:NP:6445::::::
sys:NP:6445::::::

nawk -F: -v OFS=: '{
if($1 ~ "root" || $1 ~ "daemon" ){print $1,"yes:" $2,$3,$4,$5,$6,$7,$8}
else { print $0 }
}' passwdlist > new2

output :

root:yes:6GNlhvGxH3jOk:6445:::::
daemon:yes:asasda:6445:::::bin:NP:6445::::::
sys:NP:6445::::::

But when i try to embed it in my script it doesnt work,

$ cat test1
rm file1
rm new2
for x in `cat userlist`
do

for i in `cat passwdlist | grep -w $x | awk -F: '{print $2}'`
do
a=NP
if [ $a != $i ]
then
echo " $x are not equal to NP" >> file1
fi

for n in `cat file1|awk '{print $1}'`
do
awk -F: -v OFS=: '{
if($1 ~ "$n" ){print $1,"yes:" $2,$3,$4,$5,$6,$7,$8}
else { print $0 }
}' passwdlist > new2

done
done
done
clear
cat new2

of course i changed root, daemon to $n, i dont want to declare those vaules, what if i have plenty of accoutns that i want to disabled. Hope someone could get it

Your script shows 'awk' & not 'nawk' ?!

it was the same sir, i guess it doesnt recognize the variable $i. doesnt work.

$cat userlist
root
daemon
sys
bin
lp
uucp
nobody

$cat passwdlist
root:6GNlhvGxH3jOk:6445::::::
daemon:asasda:6445::::::
bin:NP:6445::::::
sys:NP:6445::::::

for i in `cat userlist`
do
nawk -F: -v OFS=: '{
if($1 ~ "$i" ){print $1,"yes:" $2,$3,$4,$5,$6,$7,$8}
else { print $0 }
}' passwdlist > new2
done

Change this:

nawk -F: -v OFS=: '{

To:

nawk -F: -v OFS=: -v i=$i '{

And change this:

if($1 ~ "$i" ){print $1,"yes:" $2,$3,$4,$5,$6,$7,$8}

To:

if($1 ~ i ){print $1,"yes:" $2,$3,$4,$5,$6,$7,$8}

HTH

I think the problem is in the for loop logic.

Try this:

.

you are right sir, somethings wrong w/ the loop logic. But how will use (.) havent tried it before.. Right now, got a problem w/ loop. Theres a lot of problems taht i wanted to shorten by using loop,sed and awk, but in some way i wasnt get the correct output cos of loop. :frowning:

#!/usr/bin/ksh

nawk 'BEGIN{ FS=OFS=":" } {
        if (NF > 1) {
                if (arr[$1]==1)
                        $3="yes"
                        print $0
        } else
                arr[$1]=1
}' userlist passwdlist

HTH

got it :slight_smile: thanks

anyway , got question last :slight_smile: any tips how to use loops? honestly speaking im not a programmer, but i know a little how to create shell scripts, sometimes im having a hard time using loop, especially for, just like the problem occur above.

maybe you some tips there, if i will user awk programming, it will takes time for me.

thanks

$ cat shadow
root:6GNlhvGxH3jOk:6445::::::
daemon:asasda:6445::::::
bin:NP:6445::::::
sys:NP:6445::::::
$
$
$ cat userlist
root
daemon
$
$
$
$
$ cat fixit
#! /usr/bin/ksh

userlist=" $(echo $(< userlist)) "
exec < shadow
while IFS=: read username password lastchg min max warn inactive expire flag ; do
        if [[ $userlist = *${username}* ]] ; then
                password="yes"
        fi
        echo ${username}:${password}:${lastchg}:${min}:${max}:${warn}:${inactive}:${expire}:${flag}
done
exit 0
$
$
$
$
$ ./fixit
root:yes:6445::::::
daemon:yes:6445::::::
bin:NP:6445::::::
sys:NP:6445::::::
$

I am not sure what is the extent of your requirement. If you need to work with small & simple files occassionally, no problems. But if you need to work with bigger files, I suggest you remember one of the most cliched lines of programming:

Loops are expensive. Avoid them whenever you can.

Coming to your question, if you don't want to get into awk etc., you can do this:

#!/usr/bin/ksh

while read i ; do
        username=$(echo $i |cut -d":" -f1)
        matchingline=$(grep -h "^${username}$" userlist)
        if [ "${matchingline}x" = "x" ] ; then
                echo $i
        else
                echo $(echo $i |cut -d":" -f1-2)":yes:"$(echo $i |cut -d":" -f4-)
        fi
done < passwdlist

Gives the same result & is horrible. There are n number of ways of doing this using loops.

I remember once I had to re-generate UIDs for a password file with about 10k entries. I wouldn't dream of doing that using the above "loops" - awk would be my choice anyday.

HTH

thanks sir's. to soultions and tips.