Sed delete first line from files
Asked Answered
M

1

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

Melia answered 9/12, 2017 at 20:7 Comment(5)
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.Jampan
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. ... forums.freebsd.org/threads/50187 and also here #19591480Halftruth
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.Melia
I'm not sure why -i '' is required? it works just fine for me with sed -i -e ...Consult
@PhilippGrigoryev the -i '' is required with BSD sed, but not with GNU sed.Ogletree
O
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
Ogletree answered 10/12, 2017 at 5:30 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.