What I want to do is
.txt
extension.dat
fileit could do like this:
for f in `find . -type f -name "*.txt"`; do cp $f ${f%.txt}.dat; done
I want to do this with xargs, I have tried this:
find . -type f -name "*.txt" | xargs -i cp {} ${{}%.txt}.dat
I go error like this:
bad substitution
About this, I have these questions:
xargs
will do things parallel when for loop
do things one by one?xargs options : -0 : input items are terminated by null character instead of white spaces. -a file : read items from file instead of standard input.
-n1 tells xargs to run the given command once per argument. So if you have something like echo file1 file2 file2 | xargs basename. That's equivalent to basename file1 file2 file2.
xargs cannot use a builtin, but it can use any external command such as ls or echo (which is also a built-in in many modern shells, but still available as /bin/echo in order for, well, this to work) or printf .
- How to do the substitution rightly?
You cannot use substitution in the way you are trying to do because {}
is not a bash variable (only part of xargs syntax), therefore bash cannot do substitution on it.
A better way to it would be to create a full bash command and provide it as and argument to xargs (e.g. xargs -0 -i bash -c 'echo cp "$1" "${1%.txt}.dat"' - '{}'
- this way you can do bash substitution).
- I am curious about that xargs will do things parallel when for loop do things one by one?
Yes, for
loop will do things sequently but by default xargs always will. However, you can use -P
option of xargs
to parallelize it, from xargs
man pages:
-P max-procs, --max-procs=max-procs Run up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time. Use the -n option or the -L option with -P; otherwise chances are that only one exec will be done. While xargs is running, you can send its process a
SIGUSR1 signal to increase the number of commands to run simultaneously, or a SIGUSR2 to decrease the number. You cannot increase it above an implementation-defined limit (which is shown with --show-limits). You cannot de‐ crease it below 1. xargs never terminates its commands; when asked to decrease, it merely waits for more than one existing command to terminate before starting another.
Please note that it is up to the called processes to properly manage parallel access to shared resources. For example, if
more than one of them tries to print to stdout, the ouptut will be produced in an indeterminate order (and very likely mixed up) unless the processes collaborate in some way to prevent this. Using some kind of locking scheme is one way to prevent such problems. In general, using a locking scheme will help ensure correct output but reduce performance. If you don't want to tolerate the performance difference, simply arrange for each process to produce a separate output file (or otherwise use separate resources).
You can use:
find . -type f -name "*.txt" -print0 |
xargs -0 -i bash -c 'echo cp "$1" "${1%.txt}.dat"' - '{}'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With