6

I want to remove the first line of all files in a folder if the file starts with uuid and so I have a working sed command looking like this:

$ sed -i '' '/^uuid/d' *

which works fine and removes all lines starting with uuid.

Now I want to improve the script by only removing the first line if it starts with uuid since some of the files has multiple uuid:s and only the one on the first line should be deleted. So now I improved the command to look like this:

$ sed -i '' '1{/^uuid/d;}' *

Now this command also works but only on the first file in the folder and even if I run a simple (just remove first line) version like:

$ sed -i '' '1d' *

it still only affects the first file.

Why is this?

I'm on Mac (so the BSD version of sed as I've come to understand) and I also tried installing the gnu-sed version via Brew, $ brew install gnu-sed --with-default-names, with no luck.

I've read sed - 25 examples to delete a line or pattern in a file, sed - 20 examples to remove / delete characters from a file and googled sed delete first line in files

UPDATE 1: As proposed in the comments by john1024 I've tested with the -s option but not sure how to use it.

$ sed -s '1d' ./* sed: illegal option -- s

When I check man sed I can find the -s & --seperateoption so I must do something wrong here.

UPDATE 2: Ok, progress ... find . -iname '*.yml' -exec sed -i '' -e '1{/uuid/d;}' {} \; does the trick but I get error message saying sed: can't read : No such file or directory

Thanks for any help or guidance!

:ola

ola
  • 448
  • 5
  • 11
  • 4
    To solve this problem on GNU sed (Linux), one uses the `-s` option to tell sed to considers the "files as separate rather than as a single, continuous long stream." Someone who is familiar with BSD sed will have to tell you if there is a similar option on Macs. – John1024 Dec 09 '17 at 20:41
  • 3
    It seems that is common secret that bsd sed does not support -s switch , so other fellows suggest either to use a kind of loop to process all files (i.e `find ...... |sed ` or `find ... -exec sed`) . You could also try `foldername/*` or `./*` and you may get lucky. ... https://forums.freebsd.org/threads/50187/ and also here https://stackoverflow.com/questions/19590980/multiple-replacements-with-one-sed-command – George Vasiliou Dec 09 '17 at 20:54
  • Ok, so I've tried both `find ./ -iname '*.yml' | sed -e '1{/^uuid/d;}'` and `ls *.yml | sed -e '1{/^uuid/d;}'` Both which only yields a list of the files in the directory unchanged. – ola Dec 09 '17 at 22:09
  • I'm not sure why `-i ''` is required? it works just fine for me with `sed -i -e ...` – Philipp Grigoryev Dec 10 '17 at 04:19
  • 1
    @PhilippGrigoryev the `-i ''` is required with BSD sed, but not with GNU sed. – janos Dec 10 '17 at 05:30

1 Answers1

5

sed -i '' '1{/^uuid/d;}' * will modify only the first file, because the line numbers are counted cumulatively across files, so "line 1" occurs only once, it's the first line of the first file. To do something with the first line of multiple files, you need to run sed once per file.

You can do that using a simple for loop:

for f in *; do sed -i '' '1{/^uuid/d;}' "$f"; done
janos
  • 120,954
  • 29
  • 226
  • 236