how to get only one occurance of a line in a file - shell

i have a file raw-vobs-config-spec where there are two lines
element /vob/ccm_tpl/repository/open_source/ciscossl_fom/4_1/... TPLBASE
element /vob/ccm_tpl/repository/open_source/ciscossl/1_0_2d_5_4/... VERSION_04
i have my code:
OLD_VERSION=`grep "ciscossl" raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print $(NF-1)}'`
echo $OLD_VERSION
total_fields=`grep "ciscossl" raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print NF }'`
echo $total_fields
#directory_path=`grep "ciscossl" raw-vobs-config-spec | cut -d " " -f2 | cut -d"/" -f1-"${total_fields}"`
#echo $directory_path
loc=`grep "ciscossl" raw-vobs-config-spec_new | cut -d " " -f2 | cut -d"/" -f1-6`
echo $loc
so it is printing o/p as
4_1 1_0_2d_5_4
8 8
/vob/ccm_tpl/repository/open_source/ciscossl_fom
/vob/ccm_tpl/repository/open_source/ciscossl
but i need the output as
4_1
8
/vob/ccm_tpl/repository/open_source/ciscossl_fom
how can i get that?

You can use read without while loop to read just one line first and then process the read text using awk:
# read one line from input file
read _ line _ < raw-vobs-config-spec
# process the line with awk
echo "$line" | awk 'BEGIN{FS=OFS="/"} {print $(NF-1) ORS NF; NF-=2; print}'
Output:
4_1
8
/vob/ccm_tpl/repository/open_source/ciscossl_fom

Related

While Read Line - Limit Number of Lines

I am trying to limit the number of lines found during a while read line loop. For example:
File: order.csv
123456,ORDER1,NEW
123456,ORDER-2,NEW
123456,ORDER-3,SHIPPED
I am doing the following.
cat order.csv | while read line;
do
order=$(echo $line | cut -d "," -f 1)
status=$(echo $line | cut -d "," -f 3)
echo "$order:$status"
done
Which outputs:
123456:NEW
123456:NEW
123456:SHIPPED
How can I limit the number of lines. In this case there are three. How can I limit them to only 2 so that only the first two are displayed?
Desired output:
123456:NEW
123456:NEW
There are some ways to meet your requirements:
Method 1
Use head to display first few lines of a file.
head -n 2 order.csv | while read line;
do
order=$(echo $line | cut -d "," -f 1)
status=$(echo $line | cut -d "," -f 3)
echo "$order:$status"
done
Method 2
Use a for loop.
for i in {1..2}
do
read line
order=$(echo $line | cut -d "," -f 1)
status=$(echo $line | cut -d "," -f 3)
echo "$order:$status"
done < order.csv
Method 3
Use awk.
awk -F, 'NR <= 2 { print $1":"$3 }' order.csv

how to read words from a file using shell script

i have a file /ws/$1-rcd/temp.txt which has only one line as follows
198|/vob/ccm_tpl/repository/open_source/commons_collections/3_2_2/...
i have a script to get the value repository/open_source/commons_collections and 3_2_2 by reading the file and looping through it using for loop
i have my code as follows
grep -n "$4" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f1,2 | sed -e 's/\:element/|/g' | sed -e 's/ //g' > /ws/$1-rcd/temp.txt
for i in `cat /ws/$1-rcd/temp.txt`
do
line=`echo $i | cut -d"|" -f1`
path=`echo $i | cut -d"|" -f2`
whoami
directory_temp=`echo $path | awk -F "/" '{ print $(NF-2)}'`
if [ "$directory_temp" == "$4" ]
then
OLD_VERSION=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print $(NF-1)}'`
total_fields=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print NF }'`
dir_path=`expr ${total_fields} - 2`
loc=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | cut -d"/" -f1-"${dir_path}"`
location=`echo $loc | cut -d"/" -f4,5,6`
fi
done
but when i run this code it gives me an error as
-bash: line 45: syntax error near unexpected token |'
-bash: line 45:for i in 198|/vob/ccm_tpl/repository/open_source/commons_collections/3_2_2/...'
can anyone please suggest what am i doing wrong
If you want to iterate through each line of a file, use while loop like below
while read -r line ;do
echo $line
done <file.txt
so, your code can be rewritten as
grep -n "$4" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f1,2 | sed -e 's/\:element/|/g' | sed -e 's/ //g' > /ws/$1-rcd/temp.txt
while read i ; do
line=`echo $i | cut -d"|" -f1`
path=`echo $i | cut -d"|" -f2`
whoami
directory_temp=`echo $path | awk -F "/" '{ print $(NF-2)}'`
if [ "$directory_temp" == "$4" ]
then
OLD_VERSION=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print $(NF-1)}'`
total_fields=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | awk -F "/" '{ print NF }'`
dir_path=`expr ${total_fields} - 2`
loc=`sed -n "${line}p" /ws/$1-rcd/raw-vobs-config-spec | cut -d " " -f2 | cut -d"/" -f1-"${dir_path}"`
location=`echo $loc | cut -d"/" -f4,5,6`
fi
done < /ws/$1-rcd/temp.txt
You may be better served relying on parameter expansion and substring removal. For example:
#!/bin/sh
a=$(<dat/lline.txt) ## read file into a
a=${a##*ccm_tpl/} ## remove from left to ccm_tpl/
num=${a##*collections/} ## remove from left to collections/
num=${num%%/*} ## remove from right to /
a=${a%%${num}*} ## remove from right to $num
Input File
$ cat dat/lline.txt
198|/vob/ccm_tpl/repository/open_source/commons_collections/3_2_2/..
Output
$ sh getvals.sh
a : repository/open_source/commons_collections/
num : 3_2_2
If you need to trim in some other way, just let me know and I'm happy to help further.

unexpected EOF while looking for matching ``'

I try to run this script to create simple, beautiful windows with bushcurses but there is an error
~/bashcurses$ ./myfirstwindow1.sh
./myfirstwindow1.sh: line 32: unexpected EOF while looking for matching ``'
./myfirstwindow1.sh: line 39: syntax error: unexpected end of file
I have tried to add or delete '" but cannot find proper solution. Can you please help me to identify the cause of the error?
script:
#!/bin/bash
. `dirname $0`/simple_curses.sh
main (){
window "`hostname`" "red"
append "`date`"
addsep
append_tabbed "Up since|`uptime | cut -f1 -d"," | sed 's/^ *//' | cut -f3- -d" "`" 2 "|"
append_tabbed "Users:`uptime | cut -f2 -d"," | sed 's/^ *//'| cut -f1 -d" "`" 2
append_tabbed "`awk '{print "Load average:" $1 " " $2 " " $3}' < /proc/loadavg`" 2
endwin
window "Memory usage" "red"
append_tabbed `cat /proc/meminfo | awk '/MemTotal/ {print "Total:" $2/1024}'` 2
append_tabbed `cat /proc/meminfo | awk '/MemFree/ {print "Used:" $2/1024}'` 2
endwin
window "Processus taking memory and CPU" "green"
for i in `seq 2 6`; do
append_tabbed "`ps ax -o pid,rss,pcpu,ucmd --sort=-cpu,-rss | sed -n "$i,$i p" | awk '{printf "%s: %smo: %s%%" , $4, $2/1024, $3 }'`" 3
done
endwin
window "Last kernel messages" "blue"
dmesg | tail -n 10 > /tmp/deskbar.dmesg
while read line; do
append_tabbed "$line" 1 "~"
done < /tmp/deskbar.dmesg
rm -f /tmp/deskbar.dmesg
endwin
window "Inet interfaces" "grey"
ERROR >> _ifaces=$(for inet in `ifconfig | cut -f1 -d " " | sed -n "/./ p"`; do ifconfig $inet | awk 'BEGIN{printf "%s", "'"$inet"'"} /adr:/ {printf ":%s\n", $2}'|sed 's/adr://'; done)
for ifac in $_ifaces; do
append_tabbed "$ifac" 2
done
endwin
}
main_loop 1

using date variable inside sed command

I am storing date inside a variable and using that in the sed as below.
DateTime=`date "+%m/%d/%Y"`
Plc_hldr1=`head -$i place_holder.txt | tail -1 | awk -F ' ' '{ print $1 }'`
Plc_hldr2=`head -$i place_holder.txt | tail -1 | awk -F ' ' '{ print $2 }'`
sed "s/$Plc_hldr1/$DateTime/;s/$Plc_hldr2/$Total/" html_format.htm >> /u/raskar/test/html_final.htm
While running the sed command I am getting the below error.
sed: 0602-404 Function s/%%DDMS1RT%%/01/02/2014/;s/%%DDMS1C%%/1235/ cannot be parsed.
I suppose this is happening as the date contains the following output which includes slashes '/'
01/02/2014
I tried with different quotes around the date. How do I make it run?
Change the separator to something else that won't appear in your patterns, for example:
sed "s?$Plc_hldr1?$DateTime?;s?$Plc_hldr2?$Total?"
Not the direct quertion but replace
Plc_hldr1=`head -$i place_holder.txt | tail -1 | awk -F ' ' '{ print $1 }'`
Plc_hldr2=`head -$i place_holder.txt | tail -1 | awk -F ' ' '{ print $2 }'`
by
Plc_hldr1=`sed -n "$i {s/ .*//p;q}"`
Plc_hldr2=`sed -n "$i {s/[^ ]\{1,\} \{1,\}\([^ ]\{1,\}\) .*/\1/p;q}"`
and with aix/ksh
sed -n "$i {s/\([^ ]\{1,\} \{1,\}[^ ]\{1,\}\) .*/\1/p;q}" | read Plc_hldr1 Plc_hldr2

Print out onto same line with ":" separating variables

I have the following piece of code and would like to display HOST and RESULT side by side with a : separating them.
HOST=`grep pers results.txt | cut -d':' -f2 | awk '{print $1}'`
RESULT=`grep cleanup results.txt | cut -d':' -f2 | awk '{print $1}' | sed -e 's/K/000/' -'s/M/000000/'`
echo ${HOST}${RESULT}
Please can anyone assist with the final command to display these, I am just getting all of hosts and then all of results.
You probably want this:
HOST=( `grep pers results.txt | cut -d':' -f2 | awk '{ print $1 }'` ) #keep the output of the command in an array
RESULT=( `grep cleanup results.txt | cut -d':' -f2 | awk '{ print $1 }' | sed -e 's/K/000/' -'s/M/000000/'` )
for i in "${!HOST[#]}"; do
echo "${HOST[$i]}:${RESULT[$i]}"
done
A version that works without arrays, using an extra file handle to read from 2 sources at at time.
while read host; read result <&3; do
echo "$host:$result"
done < <( grep peers results.txt | cut -d: -f2 | awk '{print $1}' ) \
3< <( grep cleanup results.txt | cut -d':' -f2 | awk '{print $1}' | sed -e 's/K/000/' -'s/M/000000/')
It's still not quite POSIX, as it requires process substitution. You could instead use explicit fifes. (Also, an attempt to shorten the pipelines that produce the hosts and results. It's probably possible to combine this into a single awk command, since you can either do the substitution in awk, or pipe to sed from within awk. But this is all off-topic, so I leave it as an exercise to the reader.)
mkfifo hostsrc
mkfifo resultsrc
awk -F: '/peers/ {split($2, a, ' '); print a[1]}' results.txt > hostsrc &
awk -F: '/cleanup/ {split($2, a, ' '); print a[1]}' results.txt | sed -e 's/K/000' -e 's/M/000000/' > resultsrc &
while read host; read result <&3; do
echo "$host:$result"
done < hostsrc 3< resultsrc

Resources