Passing regular files only to `sed -i`
Solution 1
It's normal behavior. In both cases sed
exits with error code 4
... per info sed
:
4
An I/O error, or a serious processing error during runtime,
GNU 'sed' aborted immediately.
and in both cases the messages are self-explanatory. Not sure what's unclear but for the record: the first time it errors out because it cannot edit a directory and the second time it complains because it cannot edit stdin
in-place, it needs a file (i.e. remove that redirect before $file
)
The proper way to do this with find
is, as you noted, via -exec ...
With globs, you'll have to use a loop and test if input is a regular file before running sed
. Or, if you're a zsh
user, you can simply do:
sed -i 's/foo/bar/g' *(.)
Solution 2
Case 2:
Avoid that directory with
find
:sed -i 's/foo/bar/g' $(find . -maxdepth 1 -type f)
Case 3:
The problem is the
<"$file"
in the loop, that turns the file into a stream sosed
never sees a filename. Just remove that<
:for file in $(find . -maxdepth 1 -type f); do sed -i 's/foo/bar/g' "$file" done
Related videos on Youtube
Linoob
Updated on September 18, 2022Comments
-
Linoob over 1 year
I am using GNU sed 4.2.2 and after searching cannot find out the reason
sed
behaves oddly in some situations:I have a directory with the following:
foofile.txt barfile.txt bazfile.txt config/
Case 1
sed -i 's/foo/bar/g' *.txt
This works as I expect. It replaces all the "foo"s with "bar"s in the three regular files.
Case 2
sed -i 's/foo/bar/g' * sed: couldn't edit config: not a regular file
It replaces "foo" with "bar" in
barfile.txt
andbazfile.txt
, but not infoofile.txt
. I assume it goes through the list of files expanded from the*
alphabetically, and when it hitsconfig/
it errors and exits. Is there a way to havesed
ignore errors and continue processing files?Case 3
for file in $(find . -maxdepth 1 -type f); do sed -i 's/foo/bar/g' <"$file"; done sed: no input files sed: no input files sed: no input files
Could someone please explain why
sed
does this? Why does it say there's no input file when it's being given one?I know that I can use the following but I'm asking why sed acts this way, not how do I solve this one use case.
find . -maxdepth 1 -type f -exec sed -i 's/foo/bar/g' {} \;
-
Linoob about 7 yearsI think I understand how Case 3 is working now thank you. Do you know how to make
sed
continue even if it encounters an error like in Case 2? -
don_crissti about 7 years@Linoob - no; I think the man page is pretty clear: "GNU 'sed' aborts immediately"