xargs command

Hi

The command below does not work. what I am doing wrong ?
For some reason second part of the xargs command is not does what I expect
If I get this working I intend to use it for multiple file rename later.

echo archDP105144_1_702159963.dbf|xargs -i cp {} `echo {}|awk '{sub(/DP1/,"TML");print}'`

with set -x

echo archDP105144_1_702159963.dbf|xargs -i cp {} `echo {}|awk '{sub(/DP1/,"TML");print}'`
++ echo '{}'
+ echo archDP105144_1_702159963.dbf
++ awk '{sub(/DP1/,"TML");print}'
+ xargs -i cp '{}' '{}'

Thanks

xargs -I

Thanks for prompt reply. But it does not work for me. Did you try it in your environment? I tried on linux BASH and Sun KSH

echo archDP105144_1_702159963.dbf|xargs -I cp {} `echo {}|awk '{sub(/DP1/,"TML");print }'`
++ echo '{}'
+ echo archDP105144_1_702159963.dbf
++ awk '{sub(/DP1/,"TML");print }'
+ xargs -I cp '{}' '{}'
xargs: {}: No such file or directory

why can't you use simple for loop?

 
for file in *DP1*.dbf ; do
cp ${file} `echo ${file}|awk '{sub(/DP1/,"TML");print}'`
done
echo archDP105144_1_702159963.dbf|xargs -i cp {} `echo archDP105144_1_702159963.dbf |awk '{sub(/DP1/,"TML");print}'`

This won't help him in renaming multiple files.

for i in *D1P*.dbf
do
cp $i "${i%%D1P*}TML${i##*D1P}"
done

Note that my code assume the D1P pattern does not occure more than once per filename

$ ls -1 *D1P*
archD1P_10_whatever.dbf
archD1P_1_whatever.dbf
archD1P_2_whatever.dbf
archD1P_3_whatever.dbf
archD1P_4_whatever.dbf
archD1P_5_whatever.dbf
archD1P_6_whatever.dbf
archD1P_7_whatever.dbf
archD1P_8_whatever.dbf
archD1P_9_whatever.dbf
$ for i in *D1P*
> do
> echo cp $i "${i%%D1P*}TML${i##*D1P}"
> done
cp archD1P_10_whatever.dbf archTML_10_whatever.dbf
cp archD1P_1_whatever.dbf archTML_1_whatever.dbf
cp archD1P_2_whatever.dbf archTML_2_whatever.dbf
cp archD1P_3_whatever.dbf archTML_3_whatever.dbf
cp archD1P_4_whatever.dbf archTML_4_whatever.dbf
cp archD1P_5_whatever.dbf archTML_5_whatever.dbf
cp archD1P_6_whatever.dbf archTML_6_whatever.dbf
cp archD1P_7_whatever.dbf archTML_7_whatever.dbf
cp archD1P_8_whatever.dbf archTML_8_whatever.dbf
cp archD1P_9_whatever.dbf archTML_9_whatever.dbf
$

(here i put a "echo" just to display the command so that you can check it behaves has expected, if ok, then just remove the 'echo' and rerun the 'for' loop with the real cp command

your code is missing {} after -I see below :-

echo archDP105144_1_702159963.dbf| xargs -I{} cp {} `echo {}|awk '{sub(/DP1/,"TML");print}'`

BR

if there is only one file, using xargs is not optimal
you could just

cp archDP105144_1_702159963.dbf `echo archDP105144_1_702159963.dbf | awk '{sub(/DP1/,"TML");print}'`

or

f=archDP105144_1_702159963.dbf; cp $f "${f%%DP1*}TML${f##*DP1}"

how about something simpler and w/o xargs...

ls -1 archDP1* | awk '{f=$0;sub("DP1", "TML");system("cp "f" "$0)}'

{} is not expanded by the shell. It is expanded by xargs after it starts executing. However, xargs cannot be exec'd until all of its command line arguments are known. This requires the shell to invoke a subshell to perform the command subsitution in backticks. Note that at this point xargs is not running. echo {} will always yield nothing but {}. In AWK, the sub() function has nothing to do since there's no DP1 to replace, and the output is the same as what's echoed. Then the shell, finally knowing the result of the command substitution, can execute xargs. xargs will then always be passed {} {} as its final two parameters.

In short, this approach cannot be made to work.

I suggest ctsgnb's suggestion:

Regards,
Alister

1 Like

Thankyou ALL!:b:

---------- Post updated at 05:07 PM ---------- Previous update was at 04:51 PM ----------

The code I ended up with!

#!/bin/ksh
for i in *.dbf
do
    echo
    echo "... renaming $i to ${i/DP1/TML}"  
    echo -e "y - continue / n - Skip / Ctrl+C - abort  --> \c"
    read ans
     if [ "$ans" = "y" ]; then
       mv $i ${i/DP1/TML}
     else
       echo skipping $i
     fi
done