开发者

Copying files in multiple subdirectories in the Linux command line

开发者 https://www.devze.com 2023-03-18 08:49 出处:网络
Let\'s say I have the following subdirectories ./a/, ./b/, ./c/, ... That is, in my current working directory are these subdirectories a/, b/ and c/, and in each of these subdirectories are files

Let's say I have the following subdirectories

./a/, ./b/, ./c/, ... 

That is, in my current working directory are these subdirectories a/, b/ and c/, and in each of these subdirectories are files. In directory a/ is the file a.in, in directory b/ is the file b.in and so forth.

I now want to copy each .in file to a .out file, that is, a.in to a.out and b.in to b.out, and I want them to reside in the directories they were copied from. So a.out will be found in 开发者_StackOverflow中文版directory a/.

I've tried various different approaches, such as

find ./ -name '*.in'|cp * *.out

which doesn't work because it thinks *.out is a directory. Also tried

ls -d */ | cd; cp *.in *.out

but it that would list the subdirectories, go into each one of them, but won't let cp do it's work (which still doesn't work)

The

find ./ -name '*.in'

command works fine. Is there a way to pipe arguments to an assignment operator? E.g.

find ./ -name '*.in'| assign filename=|cp filename filename.out

where assign filename= gives filename the value of each .in file. In fact, it would be even better if the assignment could get rid of the .in file extension, then instead of getting a.in.out we would get the preferred a.out

Thank you for your time.


Let the shell help you out:

find . -name '*.in' | while read old; do
    new=${old%.in}.out # strips the .in and adds .out
    cp "$old" "$new"
done

I just took the find command you said works and let bash read its output one filename at a time. So the bash while loop gets the filenames one at a time, does a little substitution, and a straight copy. Nice and easy (but not tested!).


Try a for loop:

for f in */*.in; do
    cp $f ${f%.in}.out;
done

The glob should catch all the files one directory down that have a .in extension. In the cp command, it strips off the .in suffix and then appends a .out (see Variable Mangling in Bash with String Operators)

Alternatively, if you want to recurse into every subdirectory (not just 1 level deep) replace the glob with a find:

for f in $(find . -name '*.in'); do
    cp $f ${f%.in}.out;
done


This should do the trick!

for f in `find . -type f -name "*.in"`; do cp $f `echo $f | sed 's/in$/out/g'`; done
0

精彩评论

暂无评论...
验证码 换一张
取 消