Double quotes and asterisk filename extension in Bash

In catalogs ~/temp/a/foo/and ~/temp/b/foo foo/I have several files with the names bar1, bar2, bar bar1, bar bar2, etc.

I am trying to write a Bash line that copies all of these files to a directory containing "foo" as the last part of the name, in the folder located above the corresponding "foo" folder.

While there are no spaces in the file names, this is not an easy task, but two commands do not work when working with the directory foo foo:

for dir in `find . -type d -name '*foo'` ; do cp $dir/* "$(echo $dir|sed 's_foo__g')" ; done

(The command cpdoes not see the last fooof "foo foo"as part of the same directory name.)

for dir in `find . -type d -name '*foo'` ; do cp "$dir/*" "$(echo $dir|sed 's_foo__g')" ; done

( "$dir/*"doesn't turn around.)

Attempts to replace $dir/*with "$(echo $dir/*)"even less successful.

Is there an easy way to expand $dir/*to cpunderstand?

+5
source share
3 answers

Not only the wrong cycle for- sedalso not suitable for this task.

while IFS= read -r -d '' dir; do
  cp "$dir" "${dir/foo/}"
done < <(find . -type d -name '*foo' -print0)

Using -print0in find(and IFS= read -r -d '') ensures that file names with newlines do not spoil you.

Using the construction < <(...)ensures that if variables, the state of the change catalog, or similar things are set inside your loop, these changes will be saved (the right side of the pipeline is in a subshell in bash, so the pipeline into the while loop will mean that any changes to the state of the shell made inside this while the loop will be discarded on its output otherwise).

${dir/foo/} , sed, bash.

+4

cp, for, , .

- while :

find . -type d -name '*foo' | while read dir; do cp "$dir"/* "$(echo $dir | sed 's_foo__g')" ; done

, .

. .

+2

~/temp/b/foo foo/ , . ~/temp/b/foo_foo/ , . , , . . , , , , .

0

All Articles