I have a mongodump which I want to import apparently I'm looking to do this using the find
command. Something like this:
find *.bson -type f -exec echo mongoimport --db=abc --collection=$(echo '{}' | sed s/.bson//g) {} \;
What I'm looking isn't get evaluate what I need is
mongoimport --db=abc --collection=a a.bson
but I'm getting is
mongoimport --db=abc --collection=a.bson a.bson
My version of using sed
to strip the .bson
suffix from '{}'
isn't working. I know its not a blocker but I felt if that is possible.
Any suggestions?
CodePudding user response:
The problem twofold:
Shell expansions: Before a command is executed in a shell environment, the shell (sh/bash/ksh/zsh) will perform a sequence of expansions to build up the actual command that is being executed. There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion. Hence, before the
find
command will be executed, it will perform all substitutions, including the command substitution located in theexec
statement. Ergo, the command is equivalent to:$ find *.bson -type f -exec echo mongoimport --db=abc --collection={} {} \;
A way forward would be to prohibit the command substitution by using single-quotes, however this leads to problem two.
find
's exec statement is limited: The command that -exec can execute is limited to an external utility with optional arguments. Various shell features are therefor not recognized. To use shell built-ins, functions, conditionals, pipelines, redirections etc. directly with-exec
is not possible, unless wrapped in something like ash -c
child shell.
Hence the answer would be something in the line of:
$ find *.bson -type f -exec /usr/bin/sh -c 'echo mongoimport --db=abc --collection=$(echo {} | sed s/.bson//g) {}' \;
CodePudding user response:
Suggesting different strategy to this problem.
Use find
with option -printf
to prepare your commands.
The result will be list of commands to execute (command per line).
After inspecting and testing the commands, save find
command output into a file and run the file (as a bash
script).
Or just run directly into bash
command.
1. find
result inspection:
find . -type f -name "*.bson" -printf "mongoimport --db=abc --collection=%f %f\n" | sed s/.bson//
Notice sed
replacement only on first .bson
match. Do not use g
option.
2. Run processed and inspected find
output.
bash <<< $(find . -type f -name "*.bson" -printf "mongoimport --db=abc --collection=%f %f\n" | sed s/.bson//)