I have a .bd document which has lines for each book that I have. Each book has the title, author, etc divided by a \t
. The last character of each line can be 1 or 0 depending on whether the book is borrowed or not. I need a way to change that number change the state of a book by using the id (first number of the line).
1 title1 author1 genre1 year1 shelv1 0
2 title2 author2 genre2 year2 shelv2 0
3 title3 author3 genre3 year3 shelv3 0
To change status of id 2 to 1:
awk -v id=2 -v status=1 'BEGIN{FS=OFS="\t"} $1==id {$NF=status}1' file
Output:
1 title1 author1 genre1 year1 shelv1 0
2 title2 author2 genre2 year2 shelv2 1
3 title3 author3 genre3 year3 shelv3 0
See: 8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR
based on the assumption that all ids are integers:
$ awk -v ids='1 3' '
BEGIN{FS=OFS="\t"}
ids~"(^| )"$1"( |$)"{$NF=!$NF}
1' file
1 title1 author1 genre1 year1 shelv1 1
2 title2 author2 genre2 year2 shelv2 0
3 title3 author3 genre3 year3 shelv3 1
to update file
with above command's output:
awk ... file > tmpfile && mv tmpfile file
note that above script is not scalable at all, it will take too much time to process a file consisting of >1000 lines. if you need an efficient one and won't mind its length, here it is:
awk -v ids='1 3' '
BEGIN {
split(ids,p)
for(i in p) q[p[i]]
FS=OFS="\t"
}
($1 in q) {
$NF=!$NF
}
1' file
I also wrote one that doesn't create two arrays but then thought it isn't worth it.