Reputation: 8188
I have a set of 30+ files containing key-value pairs or translated strings in the format:
key=some text
Sometimes I want to delete some keys from these files and what I do is open one of them, locate the line that contains the key I want to delete (e.g. line 310) and then manually delete that line from the other files. Keys in these files are sorted alphabetically, hence if a the key appears on line 310 of a file, then it appears in line 310 of every other file.
What would be an easy way to delete a line by number (e.g. line 310) from a bunch of files?
Upvotes: 1
Views: 210
Reputation: 530
sed -i '' '310d' file1 file2 ...
will delete line 310 from all files specified keeping no backup copies. The full procedure as defined by you goes like this:
KEY=mykey
FILE1=myfile
ALL_FILES="file1 file2 ..."
sed -i '' $(grep -n "^$KEY=" $FILE1 | head -1 | sed -E 's/^([0-9]+):.*/\1/')d $ALL_FILES
but a simpler approach is:
KEY=mykey
ALL_FILES="file1 file2 ..."
sed -i '' "/^$KEY=/d" $ALL_FILES
which means "delete every line starting with 'mykey=' from $ALL_FILES keeping no backup copies".
Upvotes: 4
Reputation: 37318
Expanding on user000001 idea, here's a more general approach.
sed -i.bak "$(grep -n keyTarget keyFile|sed 's/:.*$//')d;" files*
Assuming your sed supports the -i option (most do).
You could even put this in a script and so than rather than editing keyTarget
each time, you would just use a command-line parameter by use instead of keyTarget
, ${@}
.
To confirm this will work as you expect, confirm you only get one line number back from the internal part
grep -n keyTarget keyFile|sed 's/:.*$//'
Until you're very certain that you never find a case where line numbers are off, I would save the whole collections of files to a backup dir.
Having the script support editing multiple targets gets risker, but could be done . If you like this and it works for you needs, but you could use multiple targets, post a new question, showing where you are stuck.
IHTH
Upvotes: 1