6

I have hundreds of *.txt files which have a common format.

I can insert a comma at a specific position in one file, how can I generalize the below code to apply this operation at several places for all *.txtfiles in the directory?

sed -i 's/^\(.\{4\}\)/\1,/' blank.txt

For example inserting commas at positions 4, 8, 22 etc.

Something like this perhaps?

for i in *.txt; do
   sed -i 's/^\(.\{4\}\)/\1,/' $i
done
  • Are the locations specific, or do you still need a regex to match appropriate bits? – thrig Feb 3 '16 at 23:24
  • If, for example, you need to place a comma after the fifth character, sed s/^...../&,/ /path/to/file will do it. – DopeGhoti Feb 3 '16 at 23:47
  • In addition to the other answers provided, your first command could be simplified from s/^\(.\{4\}\)/\1,/ to s/^.\{4\}/&,/ and still be usable as an ex command or within vi. (Of course it could be further simplified to s/./&,/4 for use in sed.) – Wildcard Feb 4 '16 at 8:15
8

Start from the rightmost one:

sed -i 's/./&,/22;s/./&,/8;s/./&,/4' ./*.txt

Otherwise, the first substitution would affect the offset for the second. You can always account for it though:

sed -i 's/./&,/4;s/./&,/9;s/./&,/24' ./*.txt
7

In a general way, you can just do:

sed 's/./&,/4' <in >out

That will append a comma on output to the 4th character of all input lines with at least that many characters.

And, if you'll take my advice, you should generally not use the -i switch to any sed which offers one.

  • Can you please explain your refrain from -i? Without it the process of changing a file is mv file file.new;sed '...' < file.new > file;rm file.new which is cumbersome and unsafe against multiple users. In place editing has the additional advantage that given a small enough file (under the system default buffer size, which is quite large for text files) the edit is atomic in respect to other users) – Guss Feb 4 '16 at 6:24
  • 1
    @Guss - you describe it very well - though thats not the only way. -i doesn't edit the file but replaces it. It is especially a problem for multi-user systems, because, counterintuitively, the file's permissions don't matter and only it's parent directory's permissions do. -i alters metadata - maybe even ownership. The mv file.new file.old command you detail is exactly what sed does, only it doesn't advertise that fact, nor does it respect such norms as $TMPDIR nor even ~ and just writes to the read file's parent directory while it works, before mv it over the read file at exit. – mikeserv Feb 4 '16 at 6:35
  • Yes, you are correct - I was confusing with another program. Though sed -i does retain some metadata, under (what I believe is) acceptable measures given specific conditions. For specific details, see this answer - unix.stackexchange.com/a/146054/4323 . – Guss Feb 4 '16 at 7:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.