Here is my .bowerrc:
{
"directory": "vendor/assets/bower",
"scripts": {
"postinstall": "find ./vendor/assets/bower -name '*.html' -print0 | xargs -0 sed -i '' -E -e 's/href=\"https?:\\/\\//href=\"\\/\\//g'"
}
}
This is suppose to replace all instances of href="https:// with href="//. I did this to fix a bug with my build system.
I'm getting this error:
bower postinstall find ./vendor/assets/bower -name '*.html' -print0 | xargs -0 sed -i '' -E -e 's/href="https?:\/\//href="\/\//g'
bower postinstall find: [object Object]: unknown primary or operator
bower ECMDERR Failed to execute "find ./vendor/assets/bower -name *.html -print0 [object Object] xargs -0 sed -i -E -e s/href="https?:\/\//href="\/\//g", exit code of #1 find: [object Object]: unknown primary or operator
Additional error details:
find: [object Object]: unknown primary or operator
Why is the pipe character converted to [object Object]? How do I make the command run?
I tried adding an escaped slash in front of the |:
"postinstall": "find ./vendor/assets/bower -name '*.html' -print0 \\| xargs -0 sed -i '' -E -e 's/href=\"https?:\\/\\//href=\"\\/\\//g'"
Now I'm getting:
bower ECMDERR Failed to execute "find ./vendor/assets/bower -name *.html -print0 | xargs -0 sed -i -E -e s/href="https?:\/\//href="\/\//g", exit code of #1 find: |: unknown primary or operator
I'm on OSX 10.10.5
I'm pretty sure Bower won't support this command. Have a look at this issue. It seems to work only on smallish commands like gulp postInstall for example. The reason being seems to make some assumptions about the command.
I think a fix would be to write this into a bash script, and run this bash script instead. So save this as 'postInstall.sh' with executable perms, and then change .bowerrc to have in the postInstall 'postInstall: ./postInstall.sh'
Related
I have crafted this sed command which looks to be working fine, only it's being applied to all the files in my directory :
find . -type f -name '*.js' -not -path './node_modules/*' -exec sed -i .bak -E '
1i\
const env = require('\''env-var'\'');
s/(^|[^[:alnum:]_])process\.env\.([[:alnum:]_]+) \|\| ([[:alnum:]_]+)($|[^[:alnum:]_])/\1env.get('\''\2'\'').default('\''\3'\'')\4/g
s/(^|[^[:alnum:]_])process\.env\.([[:alnum:]_]+)($|[^[:alnum:]_])/\1env.get('\''\2'\'')\3/g
' {} \;
I wish to apply those transformations only to the files which match this grep command :
grep -r "process\.env\." --exclude-dir=node_modules
I tried using the pipe but I can't make the two working together. What's the right way to handle it?
EDIT: I tried this
➜ app-service git:(chore/adding-env-example) ✗ grep -r "process\.env\." --exclude-dir=node_modules | sed -i .bak -E '
1i\
const env = require('\''env-var'\'');
s/(^|[^[:alnum:]_])process\.env\.([[:alnum:]_]+) \|\| ([[:alnum:]_]+)($|[^[:alnum:]_])/\1env.get('\''\2'\'').default('\''\3'\'')\4/g
s/(^|[^[:alnum:]_])process\.env\.([[:alnum:]_]+)($|[^[:alnum:]_])/\1env.get('\''\2'\'')\3/g
' {} \;
sed: {}: No such file or directory
I want only the files containing process.env.SOMETHING to be edited.
Work with pipes. xargs comes handy:
find ... -print |
xargs -d '\n' grep -l 'regex' |
xargs -d '\n' sed 'stuff'
xargs: illegal option -- d
You can:
install GNU xargs
install GNU parallel
write a bash loop to read the files line by line, see https://mywiki.wooledge.org/BashFAQ/001
make sure your files do not have spaces or tabs or newlines in filnames and just remove -d '\n' option.
Suggesting to reverse order of commands. sed on filtered list of files.
Files filter is combination of grep filter on find filter: grep -l "process\.env\." $(find . -type f -name '*.js' -not -path './node_modules/*').
sed -i .bak -E '
1i\
const env = require('\''env-var'\'');
s/(^|[^[:alnum:]_])process\.env\.([[:alnum:]_]+) \|\| ([[:alnum:]_]+)($|[^[:alnum:]_])/\1env.get('\''\2'\'').default('\''\3'\'')\4/g
s/(^|[^[:alnum:]_])process\.env\.([[:alnum:]_]+)($|[^[:alnum:]_])/\1env.get('\''\2'\'')\3/g
' $(grep -l "process\.env\." $(find . -type f -name '*.js' -not -path './node_modules/*'))
When running the find command, it may output "No such file or directory" errors.
As answered to the find - suppress "No such file or directory" errors question here: https://stackoverflow.com/a/45575053/7939871, redirecting file descriptor 2 to /dev/null will happily silences error messages from find, such as No such file or directory:
find yada-yada... 2>/dev/null
This is perfectly fine, as long as not using -exec to execute a command. Because 2>/dev/null will also silence errors from the executed command.
As an example:
$ find /root -exec sh -c 'echo "Error" >&2' {} \; 2>/dev/null
$ find /root -exec sh -c 'echo "Error" >&2' {} \;
Error
find: ‘/root’: Permission denied
Is there a way to silence errors from find while preserving errors from the executed command?
Using -exec option in find command is integration of xargs command into find command.
You can alwayes separate find from -exec by piping find output into xargs command.
For example:
find / -type f -name "*.yaml" -print0 2>/dev/null | xargs ls -l
If for some reason you can't use:
find . -print0 2>/dev/null | xargs -0 ...
Then here's a POSIX way to do the same thing:
find . -exec sh -c '"$0" "$#" 2>&3' ... {} + 3>&2 2>/dev/null
note: 3>&2 is located before 2>/dev/null
I use the following command in Git Bash to search for Java classes using non ASCII characters:
find */src/*/java -name "*.java" -print0 | xargs -0 ggrep -lP "[\x80-\xFF]"
I get the error:
xargs: ggrep: no such file or directory
Any other way to run this command in Windows 7?
I'm trying to get rid off all my Dropbox files including "File foo in conflict with copy from ..." I tried several lines of code but non of them worked so far :(
find | grep conflict | xargs -0 rm ""
Error: filename too long for rm because there is no file/line separator
When i use the following:
find | grep conflict | head -1 | xargs rm ""
I get errors because the filename contains spaces. What line of code should I choose to get rid of this problem?
You don't need xargs, you can do it directly with find:
find . -name '*conflict*' -delete
Alternatively, you could execute rm:
find . -name '*conflict*' -exec rm -- {} \+
-- prevents problems with file names that start with a dash. (Hat tip: mklement0)
find . -name '*conflict*' -print0 | xargs -0 rm
I'm getting an error with the following
find . -name "*" -type f | xargs grep -l "xyz" | sed -i '' 's/'${line}'/'${rep}'/g'
sed: -i may not be used with stdin
what's gone wrong?
Asuming that you're trying to sed something only in the files that contain xyz, you will have to xargs again
find . -name "*" -type f | xargs grep -l "xyz" |xargs sed -i "s/'${line}'/'${rep}'/g"
-i is for inline file editing and you are just piping find command's output to sed in stdin hence that error shows up.
Try this find command instead:
find . -name "*" -type f -exec sed -i '' "s/${line}/${rep}/g" '{}' \;
PS: -name "*" can also be skipped here.
When we are using the find command we can't connect the output with the pipe( | ). So you can use the -exec with find command to execute more commands.