Unable to copy a file with '$' in name in Linux
The shell will interpret $Config
as a variable. And it will expand to empty string.
You can put single quotes around to keep the literal value:
cp 'TopSample$Config.class' /home/praveen/com/config/
Another way is to escape the $
(dollar sign) by using \
(backslash)
cp TopSample\$Config.class /home/praveen/com/config/
How to copy files with the same name in different source dir and rename in destination dir?
If you don't need to put everything in the same path, you could maintain the structure using --parent
:
$ cp --parent */abc.zip ~/dest
$ tree ~/dest
~/dest
├── 1
│ └── abc.zip
├── 2
│ └── abc.zip
└── 3
└── abc.zip
Copy all files in folder to another folder prepending a . to the file name and rename it back to original file name
Let's suppose we have two directories as follows:
$ ls -a foo*
foo1:
. .. file1 file2 file3 'file 4'
foo2:
. ..
If we execute next command:
$ for file in foo1/* ; do base=$(basename "$file"); cp "foo1/$base" "foo2/.$base"; mv "foo2/.$base" "foo2/$base"; done
We will get at the end:
$ ls -a foo*
foo1:
. .. file1 file2 file3 'file 4'
foo2:
. .. file1 file2 file3 'file 4'
I think this is what you wanted.
Moreover, the file names with spaces inside will be correctly handled.
What characters are forbidden in Windows and Linux directory names?
A “comprehensive guide” of forbidden filename characters is not going to work on Windows because it reserves filenames as well as characters. Yes, characters like*
"
?
and others are forbidden, but there are a infinite number of names composed only of valid characters that are forbidden. For example, spaces and dots are valid filename characters, but names composed only of those characters are forbidden.
Windows does not distinguish between upper-case and lower-case characters, so you cannot create a folder named A
if one named a
already exists. Worse, seemingly-allowed names like PRN
and CON
, and many others, are reserved and not allowed. Windows also has several length restrictions; a filename valid in one folder may become invalid if moved to another folder. The rules for
naming files and folders
are on the Microsoft docs.
You cannot, in general, use user-generated text to create Windows directory names. If you want to allow users to name anything they want, you have to create safe names like A
, AB
, A2
et al., store user-generated names and their path equivalents in an application data file, and perform path mapping in your application.
If you absolutely must allow user-generated folder names, the only way to tell if they are invalid is to catch exceptions and assume the name is invalid. Even that is fraught with peril, as the exceptions thrown for denied access, offline drives, and out of drive space overlap with those that can be thrown for invalid names. You are opening up one huge can of hurt.
Is it possible to use / in a filename?
The answer is that you can't, unless your filesystem has a bug. Here's why:
There is a system call for renaming your file defined in fs/namei.c
called renameat
:
SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname)
When the system call gets invoked, it does a path lookup (do_path_lookup
) on the name. Keep tracing this, and we get to link_path_walk
which has this:
static int link_path_walk(const char *name, struct nameidata *nd)
{
struct path next;
int err;
unsigned int lookup_flags = nd->flags;
while (*name=='/')
name++;
if (!*name)
return 0;
...
This code applies to any file system. What's this mean? It means that if you try to pass a parameter with an actual '/'
character as the name of the file using traditional means, it will not do what you want. There is no way to escape the character. If a filesystem "supports" this, it's because they either:
- Use a unicode character or something that looks like a slash but isn't.
- They have a bug.
Furthermore, if you did go in and edit the bytes to add a slash character into a file name, bad things would happen. That's because you could never refer to this file by name :( since anytime you did, Linux would assume you were referring to a nonexistent directory. Using the 'rm *' technique would not work either, since bash simply expands that to the filename. Even rm -rf
wouldn't work, since a simple strace reveals how things go on under the hood (shortened):
$ ls testdir
myfile2 out
$ strace -vf rm -rf testdir
...
unlinkat(3, "myfile2", 0) = 0
unlinkat(3, "out", 0) = 0
fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
close(3) = 0
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0
...
Notice that these calls to unlinkat
would fail because they need to refer to the files by name.
Use a text file (containing file names) to copy files from current directory to new directory
To get only matching filenames from search.txt I would do this:
find . -type f -name '*.fasta' -print0 | grep -zf search.txt | xargs -r0 cp -t target-dir/
It will find all files with the extension .fasta, display only the ones with matching patterns in search.txt, and bulk cp them to target-dir, and each filename is terminated with a nullbyte in case filenames contain newlines.
a simple copy files based on names into two directory with bash
Given:
$ ls -1
part=2020-02-03
part=2020-03-02
part=2020-03-15
part=2020-05-01
part=2020-05-02
part=2020-05-03
The date part of your file names look like a form of ISO 8601 and therefore can be compared lexicographically (as strings).
Use a glob (rather than trying to parse ls
), split the file name on the =
and compare to the cutoff using string comparisons:
cut="2020-03-10"
for fn in part=*; do
if [[ "${fn#*=}" < "$cut" ]]; then
# ^ split the filename on '='
echo "$fn => dir 1"
# instead of echoing -- you would mv "$f" "new_path 1"
else
echo "$fn => dir 2"
# again -- replace with the mv you want
fi
done
This prints:
part=2020-02-03 => dir 1
part=2020-03-02 => dir 1
part=2020-03-15 => dir 2
part=2020-05-01 => dir 2
part=2020-05-02 => dir 2
part=2020-05-03 => dir 2
You should be able to take it from there!
Related Topics
Redirecting Console Output to a File in Unix
Ksh Storing Result of a Command to a Variable
Does Linux Support Memory Isolation for Processes
How to Execute Multiple Commands After Sudo Command
Best Approach to Detecting a Move or Rename to a File in Linux
How to Search for Invisible Control Characters
How to Use Find -Exec in Cmake Execute_Process
Why Is Execution Time of a Process Shorter When Another Process Shares the Same Ht Core
Syntax Error: Operand Expected When Using Bash
Nginx Loadbalancer Too Many Open Files
Is There a Subversion Web Client That I Can Use
How to Install an Older Version of PHP Using Apt-Get
"Thread Apply All Bt Full" Gives Blank in Gdb
How to Cross Compile R Packages for MACos from a Linux Environment