How to display filename only as an output of cp command?

0

1

I'm copying files from src folder to dest folder usign the command:

cp -nv /src/* /dest/ > copy_result.txt

The result of copied files is in the output file as shown below:

 « /src/test1.txt » -> « /dest/test1.txt »
 « /src/test2.txt » -> « /dest/test2.txt »

Otherwise , I want that the output file contains the filename only, without the whole path and without the file extension, like so:

test1
test2

Angelika

Posted 2019-04-04T10:51:16.373

Reputation: 23

Answers

1

Try the command

cp -nv /src/* /dest/ | awk '{print $6}' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt

awk prints the sixth field. And rev reverses the string. cut splits the string at a delimiter specified by -d, extract portion specified by -f.

Edit:
As pointed out, this is not friendly with files/directories with spaces. But this will by extracting substrings between '-> « ' and ' »' :

cp -nv /src/* /dest/ | sed -e 's/.*-> « \(.*\) ».*/\1/' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt

Davey

Posted 2019-04-04T10:51:16.373

Reputation: 549

2What about files /src/with spaces.txt? – Kamil Maciorowski – 2019-04-04T20:17:46.727

@Davey The command is working perfectly thank you for your response – Angelika – 2019-04-05T11:46:21.120

@Davey When running the bash, it says that : bash: /bin/cp: Argument list too long – Angelika – 2019-04-05T15:10:20.963

Did you make sure to include the first '|'? What OS are you on? – Davey – 2019-04-05T15:41:59.150

@Davey yes I included '|' ,It's CentOS – Angelika – 2019-04-08T08:06:02.533

@Angelika You got argument list too long because /src/* expands to too many entries. Such pattern in for loop (like in my answer) is immune to the issue: the long list exists internally in the shell only, no external tool gets a list that is too long. A loop is a common way to deal with the issue; another one is find -exec or find | xargs. – Kamil Maciorowski – 2019-04-08T08:23:02.033

0

-v is not specified by POSIX. This means each cp implementation may handle it differently (or not at all). Where your cp says « foo » my says 'foo'. It's possible to craft a command that would transform your undesired output into the desired one, still I'd like to present a solution independent from cp implementation.


After /src/* in your command expands, cp copies the resulting entries one by one. This means you can turn cp -n /src/* /dest/ into

for file in /src/*; do cp -n "$file" /dest/; done

Now it's easy to do something with $file. This will generate the output you want:

for path in /src/*; do
   file="${path##*/}"
   dst="/dest/$file"
   [ ! -e "$dst" ] && cp "$path" "$dst" && printf '%s\n' "${file%.*}"
done

(To redirect to copy_result.txt use done > copy_result.txt instead of just done).


Note if you used cp -r -v and at least one of the operands from the expansion of /src/* was a directory, cp would copy and print its contents, while the above code (after we add -r) would copy as much but print only the directory itself. -r may not be the only option that would introduce discrepancy.

So while the approach should be independent from cp implementation, it relies on some option(s) not being used. Another disadvantage is the code runs a separate cp process for every object in /src/, this is far from optimal.

There's also a race condition: if the $dst file appears between [ and cp, cp will do its job. You can use cp -n to avoid overwriting, but printf will still report the file.

Kamil Maciorowski

Posted 2019-04-04T10:51:16.373

Reputation: 38 429

thank you for your response – Angelika – 2019-04-05T11:47:04.080

Please by applying the loop, the new copied file are added with the previous copied files – Angelika – 2019-04-05T15:31:41.467

@Angelika I don't really understand your comment. Sorry, I'm not a native English speaker. Could you rephrase it? – Kamil Maciorowski – 2019-04-05T19:12:57.313

Actually when I have used the for loop, The output contains the list of new copied files and also all the previous copied files, normally only the last copied files must be shown in the output – Angelika – 2019-04-08T08:04:46.320

@Angelika OK, I get it. Added test for nonexistence. – Kamil Maciorowski – 2019-04-08T08:16:34.337

Thank you for your help now it shows the result of the last copied file – Angelika – 2019-04-08T09:46:29.927