vg77
October 30, 2014, 7:49am
1
Hi,
I would like have a shell script to check every line in a file to see if it ends with ";". If this is NOT the last character ";" should be added.
MyFile.csv :
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572
web9331805;01/01/2014 00:00:11;;"877219";352215572
web9331807;01/01/2014 00:00:14;;"624588";352215598
Should be
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572;
web9331805;01/01/2014 00:00:11;;"877219";352215572;
web9331807;01/01/2014 00:00:14;;"624588";352215598;
Any help ?
Thanks !
RudiC
October 30, 2014, 7:54am
2
Any attempt from your side?
vg77
October 30, 2014, 7:58am
3
I would use
sed 's/$/;/' MyFile.csv
to add ; but how do I check this last char for every line ?
RudiC
October 30, 2014, 8:05am
4
Please use code tags as required by forum rules!
Adapting your attempt, try
sed -E 's/(;|.)$/;/' MyFile.csv
EDIT: Don't use - wrong solution!
vg77
October 30, 2014, 8:12am
5
Thanks !
But I'm getting an invalid option -E ?
Hello vg77,
Welcome to forums, please use code tags for using commands and codes in post as per forum rules. Following may help you in same too.
awk '{$NF=$NF !~ /;$/?$NF=$NF";":$NF} 1' Input_file
Output is as follows.
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572;
web9331805;01/01/2014 00:00:11;;"877219";352215572;
web9331807;01/01/2014 00:00:14;;"624588";352215598;
Thanks,
R. Singh
cero
October 30, 2014, 8:21am
7
I tried Rudis solution without -E and it worked for me (GNU-sed).
Another possible sed-solution:
sed 's/[^;]$/;/' MyFile.csv
EDIT: wrong solution! - do not use!
RudiC
October 30, 2014, 8:24am
8
Try egrep
.
@cero : That's removing the last char!
1 Like
cero
October 30, 2014, 9:41am
9
@Rudi
thanks for the check - not my day today (didn't get enough sleep)...
RudiC,
When I try:
sed -E 's/(;|.)$/;/' MyFile.csv
it replaces the last character on every line with a semicolon instead of adding a semicolon to the end of lines that don't already have one.
Try:
sed '/[^;]$/s/$/;/' MyFile.csv
3 Likes
Longhand using builtins only, OSX 10.7.5, default shell and terminal...
#!/bin/sh
# add_char.sh
> /tmp/text
> /tmp/txt
echo 'web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572
web9331805;01/01/2014 00:00:11;;"877219";352215572
web9331807;01/01/2014 00:00:14;;"624588";352215598
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572
web9331805;01/01/2014 00:00:11;;"877219";352215572
web9331807;01/01/2014 00:00:14;;"624588";352215598
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572
web9331805;01/01/2014 00:00:11;;"877219";352215572
web9331807;01/01/2014 00:00:14;;"624588";352215598
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572
web9331805;01/01/2014 00:00:11;;"877219";352215572
web9331807;01/01/2014 00:00:14;;"624588";352215598' > /tmp/text
while read line
do
if [ "${line:$((${#line}-1)):1}" == ";" ]
then
printf "$line\n" >> /tmp/txt
else
printf "$line"';'"\n" >> /tmp/txt
fi
done < /tmp/text
cat /tmp/txt
Results...
Last login: Thu Oct 30 19:10:57 on ttys000
AMIGA:barrywalker~> cd ~/Desktop/Code/Shell
AMIGA:barrywalker~/Desktop/Code/Shell> chmod 755 add_char.sh
AMIGA:barrywalker~/Desktop/Code/Shell> ./add_char.sh
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572;
web9331805;01/01/2014 00:00:11;;"877219";352215572;
web9331807;01/01/2014 00:00:14;;"624588";352215598;
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572;
web9331805;01/01/2014 00:00:11;;"877219";352215572;
web9331807;01/01/2014 00:00:14;;"624588";352215598;
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572;
web9331805;01/01/2014 00:00:11;;"877219";352215572;
web9331807;01/01/2014 00:00:14;;"624588";352215598;
web9331801;01/01/2014 23:39:35;;"93962";353150256;
web9331802;01/01/2014 23:44:29;;"479288";353153538;
web9331803;01/01/2014 00:00:11;;"877219";352215572;
web9331805;01/01/2014 00:00:11;;"877219";352215572;
web9331807;01/01/2014 00:00:14;;"624588";352215598;
AMIGA:barrywalker~/Desktop/Code/Shell> _
More variations
sed 's/;\{0,1\}$/;/' file
GNU sed -r / BSD sed -E:
sed -E 's/;?$/;/' file
sed 's/[^;]$/&;/' file
--
For a fixed number of fields:
awk -v n=6 '{$n=x}1' FS=\; OFS=\; file
wisecracker:
Longhand using builtins only, OSX 10.7.5, default shell and terminal...
... ... ...
while read line
do
if [ "${line:$((${#line}-1)):1}" == ";" ]
then
printf "$line\n" >> /tmp/txt
else
printf "$line"';'"\n" >> /tmp/txt
fi
done < /tmp/text
... ... ...
This happens to work with the supplied sample data (since it does not contain any %
or \
characters, but it is very dangerous to use a user-supplied string as a format operand to printf
.
This would be much safer:
while read -r line
do if [ "${line:$((${#line}-1)):1}" == ";" ]
then printf '%s\n' "$line"
else printf '%s;\n' "$line"
fi
done < /tmp/text > /tmp/txt
(Note also the addition of the -r
option to read
.)
1 Like
And here's the inversed corollary of Don Cragun's code...
sed '/;$/!s/$/;/' file
Another shell version:
while IFS= read -r line
do
printf "%s\n" "${line%;};"
done < file > newfile
1 Like