Hi I am having a file which has like this content shown below
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,12-Jun,t
I need to replace last line like this
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,10-August,t
Hi I am having a file which has like this content shown below
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,12-Jun,t
I need to replace last line like this
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,10-August,t
Try : for given input, with the assumption that there is no empty new line at the end
$ tac file | awk -F, 'NR==1{$2=replace}1' OFS=\, replace=10-August | tac
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,10-August,t
OR
--edit----
$ awk -F, 'NR == 1 ; getline ; END{$2=replace;print}' OFS=\, replace=10-August file
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,10-August,t
Hi,
With sed ( no tested ) :
sed -e '$s/12-Jun/10-August/' file
This command replace first "12-Jun" by 10-August and only in last line of file.
Regards.
Hi i am having multiple files with different date at last line which s at 2nd position
is it possible to achieve to change the 2nd position date to one single date
for eg:
file1
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,12-Jun,t
file2
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,10-Jun,t
file3
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,16-Dec,t
i need to replace in all the files last line like below without affecting any other data in each of the files
file1
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,10-Aug,t
file2
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,10-Aug,t
file3
Aaa,bb,cc,dd
Xxx,yy,d,12
Dodd,10-Aug,t
sed -i '$s/,[^,]*,/,10-August,/' file1 file2
One way using tac
and awk
#!/bin/bash
# Replace here whatever you want in 2nd field
replace=10-Aug
for file in file*; do
tac $file | \
awk -F, 'NR==1{ $2 = replace}1' OFS=, replace=$replace | tac >fl.tmp && cat fl.tmp >$file
done
rm fl.tmp
Hi ,
i would say tac is not working in my shell even i tried in bash mode, can you help me how i can use tac command in sunsol OS
I assume that last line is not blank
Try :
#!/bin/bash
# Replace here whatever you want in 2nd field
replace=replaces
for file in file*; do
awk -F, 'NR == 1 ; getline ; END{$2=replace;print}' OFS=\, replace=$replace $file >fl.tmp
cat fl.tmp >$file
done
rm fl.tmp
If you want to run this on a Solaris/SunOS
system, use /usr/xpg4/bin/awk
, /usr/xpg6/bin/awk
, or nawk
instead of the default /usr/bin/awk
.
Here is an alternative way that doesn't require tac:
#!/bin/ksh
IAm=${0##*/}
if [ $# -lt 2 ]
then printf "Usage: %s replacement_string file...\n" "$IAm" >&2
exit 1
fi
rep="$1"
shift
for file in "$@"
do printf "%s: Processing file %s\n" "$IAm" "$file"
ed -s "$file" <<-EOF
\$g/\([^,]*,\)[^,]*/s//\1$rep/
w
q
EOF
done
This was tested used ksh and bash, but any shell that recognizes basic Bourne shell syntax should work just as well. It was also tested using ed and ex. On most systems ed is a little bit smaller and faster than ex, but your mileage may vary.
To use it to make the changes requested in message #4 in this thread, save the above script in a file (e.g., tester), make it executable using:
chmod +x tester
and run it with:
./tester "10-Aug" file[123]
hi it worked if i use tail -r instead of tac thanks for you help
Hi Don,
Is it possible to replace any field or coloumn irrespective of 2nd column i have mentioned or can i use the which col to be replaced by giving user input in your code ???
I'm not sure I understand what you want to do.
I am guessing that you want the script to take an additional operand that specifies which field in the last line of each file is to be replaced, as in:
ScriptName replacement_string field_number file...
If that is what you want, we could add code before the for loop to calculate a BRE to use in ed to select the given number of fields minus one to be copied before the given field is replaced.
Note that my script verified that the last line in the file did have the appropriate number of fields and silently ignores the request if the last line is not in the proper format. Would you prefer to get an error message if the last line is not in the proper format?
Hi don
Actually I need to replace the last line which comes in 4th position so is it possible to replace any position in last line using your code can you share it
If by "last line in 4th position", you mean that you want to change the 4th comma delimited field in the last line, you could try something like:
#!/bin/ksh
IAm=${0##*/}
replacement="$1"
field="$2"
if [ $# -ge 3 ]
then if [ ${#field} -eq 0 ] || [ "${field}" != "${field%*[^0-9]*}" ] ||
[ $field -eq 0 ]
then printf "%s: invalid field# <%s>\n" "$IAm" "$field" >&2
shift $#
fi
fi
if [ $# -lt 3 ]
then printf "Usage: %s replacement_string field# file...\n" "$IAm" >&2
exit 1
fi
if [ "$2" -eq 1 ]
then edCommandMiddle='[^,]*/'
else BRE=''
while [ $((field--)) -gt 1 ]
do BRE="${BRE}[^,]*,"
done
edCommandMiddle='\('"$BRE"'\)[^,]*/\1'
fi
shift 2
# printf "ed command will be: %s\n" '$'"s/^$edCommandMiddle$replacement/"
for file in "$@"
do printf "%s: Processing file %s\n" "$IAm" "$file"
ed -s "$file" <<-EOF
\$s/^$edCommandMiddle$replacement/
w
q
EOF
done
As before, the 1st operand you need to give to this script is the string you want to use to replace the current contents of the selected field. The 2nd operand is the field number for the field you want to change. And the remaining operands are pathnames to the files you want to change. So, if you named this script tester
and you want to change the 4th field of the last line in files named file1
, file2
, and file3
to "new text", use:
./tester 'new text' 4 file[123]