copy multiple files with certain prefixs - bash

How do i copy files with with the certain prefixs e.g. LTE*.html, Voicemail*.html
$ ls
2G_3G_cccccc.html other_dddd.html other3_dddd.html Voicemail_bbbbbb.html
LTE_aaaa.html other2_dddd.html subdir1
I have tried this but no joy
$ cp '(LTE*|Voice*).html' subdir1/
cp: cannot stat `(LTE*|Voice*).html': No such file or directory
So this would be the result I want
$ ls subdir1/
Voicemail_bbbbbb.html LTE_aaaa.html

Use brace expansion
cp {LTE,Voice}*.html subdir1/
Which expands to
cp LTE*.html Voice*.html subdir1/

Related

How to solve no such file or directory while using xargs

I am trying to copy a file(s) to the same directory but with a prefix. I am using xargs to do that. NOTE: I can't use cd as it will break build in my pipeline.
This is what I have
root#gotoadmins-OU:~# ls
snap test
root#gotoadmins-OU:~# ls test/
me.war
root#gotoadmins-OU:~# ls test | xargs -I {} cp {} latest-{} test/
cp: cannot stat 'me.war': No such file or directory
cp: cannot stat 'latest-me.war': No such file or directory
If I understand the question correctly, you simply want to copy all of the files in a subdirectory to the same subdirectory, but with the prefix "latest-".
find test -type f -execdir bash -c 'cp "$1" latest-"$(basename "$1")"' "$(which bash)" "{}" \;
$(which bash) can be replaced with the word bash or anything, really. It's just a placeholder.
As #KamilCuk commented, a subshell might also be an option. If you put commands inside parentheses (e.g. (cd test; for FILE in *; do cp "$FILE" latest-"$FILE"; done)), those commands are run in a subshell, so the environment, including your working directory, is unaffected.
can you just use the cp command to do this?
cp test/me.war test/latest-me.war

Odd cp behavior in bash script

I have a bash script that is copying some files, but it doesn't seem to be working properly. A side note is that there are no matching files in the source directory. But the point of the script is to copy files if there are files to copy.
A basic snippet of what I'm trying to do:
source_loc=/u01
target_log=/u02
/usr/bin/cp "$source_loc"/dir/*file* "$target_loc"/dir/
Results in
Usage: cp [-fhipHILPU][-d|-e] [-r|-R] [-E{force|ignore|warn}] [--] src target
or: cp [-fhipHILPU] [-d|-e] [-r|-R] [-E{force|ignore|warn}] [--] src1 ... srcN directory
If I add set -x to my script, I get this...
+ /usr/bin/cp /u02/dir/
Usage: cp [-fhipHILPU][-d|-e] [-r|-R] [-E{force|ignore|warn}] [--] src target
or: cp [-fhipHILPU] [-d|-e] [-r|-R] [-E{force|ignore|warn}] [--] src1 ... srcN directory
+ set +x
The EXTRA peculiar thing about this is that if I re-run the script without changing anything, I get this as my output:
cp: /u01/dir/*file*: No such file or directory
Now I haven't tested this script with matching files in the source (I will be very shortly) but I want to make sure I'm not missing something. I don't care about getting an error, I just want to be sure I get the correct error (i.e. no such file or directory).
Any insight would be appreciated.
You can use find as suggested by #elliotfrisch:
find "$source_dir/dir" -type f -name "*file*" -maxdepth 1 -exec cp {} "$target_loc/dir" \;
Alternatively, in Bash, you can capture the glob results into an array and invoke cp when the array is not empty:
shop -s nullglob # glob expands to nothing if there are no matching files
files=("$source_loc/dir/"*file*)
((${#files[#]} > 0)) && cp "${files[#]}" "$target_loc"/dir/

In bash, cp does copy dot files while using wildcard? Which option should I use

When I use
cp -r source dest,
the dot files as in .gitIgnore or any .xyz are ignored. When I use
cp -r source/.xyz dest,
then they are copied. Which option with cp can copy all the files including the dot files while using the wildcard *?
You can use the wildcard like cp -r .[^.]*
Thats because your bash is built to ignore the hidden files and cp command just don't get the hidden arguments. Thats how its supposed to work .. :)
As for me the most universal way:
cp -a /source/. /destination/
Or if you are inside of a source folder:
cp -a . /destination/
While using a wildcard *, you can try the command cp source/*.* destination/ to copy all the hidden files too.
If you want to include unhidden directories in the cp command you can try the below command
cp -r source/. destination/
Note the . at the end of source. That includes all the files and directories in the source including hidden ones.
Or
cp -r source/{.,}* destination/
x{.,}y is converted to x.y and xy. In your case it will be source/.* and source/*

bash: completely replace a folder with cp

I have a question concerning the "cp"-command:
I have to copy folders to a directory. For me two different scenarios exist. In the first scenario folders with the same name don't exist. That's simple so far:
ls test/folder1/
file1 file2
ls test/destination/
cp -r -v test/folder1/ test/destination/
»test/folder1/“ -> »test/destination/folder1“
»test/folder1/file1“ -> »test/destination/folder1/file1“
»test/folder1/file2“ -> »test/destination/folder1/file2“
In the second scenario a folder with the same name exists. These files have different names than the ones in the source folder. What I actually want is that the folder in the destination directory will be completely replaced by the source folder (if files with the same name exist they should be overriden; if files don't exist in the source directory they should be deleted).
ls test/folder1/
file1 file2
ls test/destination/
folder1
ls test/destination/folder1/
file3 file4
cp -r -v test/folder1/ test/destination/
»test/folder1/file1“ -> »test/destination/folder1/file1“
»test/folder1/file2“ -> »test/destination/folder1/file2“
ls test/destination/folder1/
file1 file2 file3 file4
It would probably be possible with something like
if [ -d destination/$foldername ]
then
rm -r /destination/$foldername
cp-r -v test/$foldername/ test/destination/$foldername
else
cp-r -v test/$foldername/ test/destination/$foldername
fi
but I was wondering if there is a better solution to that.
Thanks already!
In you second case you want to use:
cp -av test/$foldername/* test/destination/$foldername
That will copy the contents of test/$foldername to test/destination/$foldername overwriting any files of the same name that exist in test/destination/$foldername. Additionally, to preserve any (heaven forbid) spaces in $foldername you can quote the path/filename, but NOT the *:
cp -av "test/$foldername/"* "test/destination/$foldername"

Is this correct way to copy symlinked directory in bash?

I have directory a that is symlinked somewhere. I want to copy its contents to directory b. Doesn't the following simple solution break in some corner cases (e.g. hidden files, exotic characters in filenames, etc.)?
mkdir b
cp -rt b a/*
Simply adding a trailing '/' will follow the symlink and copy the contents rather than the link itself.
cp -a symlink/ dest
Bash globbing does not choke on special characters in filenames. This is the reason to use globbing, rather than parsing the output of a command such as ls. The following would also be fine.
shopt -s dotglob
mkdir -p dest
cp -a symlink/* dest/

Resources