Score:0

Failing string replacement in xargs command

tr flag

I am trying to automatically create symlinks to directories and to replace a certain text string (foo) of the original name in the link name (bar). The name of the target directories may contain spaces (e.g. "foo with whitespace").

This is a minimal example:

> ls -Q

"foo"
"foo with whitespace"

I am trying the following command (using xargs' -p option to debug/check the result before its execution):

find . -iname "*foo*" -print0 | xargs -0 -I '{}' -p ln -s {} `echo {} | sed -e s#foo#bar#g

My desired outcome is this:

ln -s 'foo with whitespace' 'bar with whitespace'
ln -s 'foo' 'bar'

However the string replacement fails. The actual output looks like this:

ln -s './foo with whitespace' './foo with whitespace'?...
ln -s ./foo ./foo?...

If I use constant strings instead of {}, the string replacement works as intended:

find . -iname "*foo*" -print0 | xargs -0 -I '{}' -p ln -s {} `echo "foo" | sed -e s#foo#bar#g`

ln -s './foo with whitespace' bar?...
ln -s ./foo bar?...

What's my mistake and how do I fix the command invocation?

Edit: Tilman Schmidt's solution works like a charm.

Score:1
bd flag

The command substitution

`echo {} | sed -e s#foo#bar#g`

is performed only once, before the pipeline composed of the find and xargs commands is run. So sed gets the string {} as input and, not finding foo, outputs it unchanged. Then the shell runs the resulting command line

find . -iname "*foo*" -print0 | xargs -0 -I '{}' -p ln -s {} {}

So command substitution is the wrong tool here. Try something like

find . -iname "*foo*" -print | while read f; do ln -s "$f" "${f//foo/bar}"; done

(untested) instead. Note that this won't work if you have filenames containing newlines.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.