Linux filenames with spaces

Bash and filenames with spaces

where listOfFiles.txt contains a list of filenames to be grepped, one filename per line. The problem occurs when listOfFiles.txt contains filenames with embedded spaces. In all cases I’ve tried (see below), Bash splits the filenames at the spaces so, for example, a line in listOfFiles.txt containing a name like ./this is a file.xml ends up trying to run grep on each piece ( ./this , is , a and file.xml ). I thought I was a relatively advanced Bash user, but I cannot find a simple magic incantation to get this to work. Here are the things I’ve tried.

grep -li 'regex' `cat listOfFiles.txt` 

Fails as described above (I didn’t really expect this to work), so I thought I’d put quotes around each filename:

grep -li 'regex' `sed -e 's/.*/"&"/' listOfFiles.txt` 

Bash interprets the quotes as part of the filename and gives «No such file or directory» for each file (and still splits the filenames with blanks)

This fails as for the original attempt (that is, it behaves as if the quotes are ignored) and is very slow since it has to launch one ‘grep’ process per file instead of processing all files in one invocation. The following works, but requires some careful double-escaping if the regular expression contains shell metacharacters:

eval grep -li 'regex' `sed -e 's/.*/"&"/' listOfFiles.txt` 

Is this the only way to construct the command line so it will correctly handle filenames with spaces?

6 Answers 6

IFS is the Internal Field Separator. Setting it to $’\n’ tells Bash to use the newline character to delimit filenames. Its default value is $’ \t\n’ and can be printed using cat -etv

Enclosing the script in parenthesis starts a subshell so that only commands within the parenthesis are affected by the custom IFS value.

Even if you don’t export it, the value will persist if this wasn’t run in a subshell. Just try running FOO=bar; echo $FOO on one line, then echo $FOO on another. Subshells are automatically started for commands in pipelines, but IFS=$’\n’ is of course not part of a pipeline here. The best solution is to surround the whole statement with parentheses, which manually tell bash to run the command in a subshell.

I still prefer running this in a subshell, but if you do want to save/restore IFS, you definitely want to quote the variable expansions.

Another way to have a variable assignment only apply temporarily is to use a space between the variable assignment and the command it applies to: IFS=$’\n’ grep -li ‘regex’ $(

@Dennis: I thought that as well, but for some reason that does not work on my machine. Perhaps that the scope of IFS=$’\n’ is so limited in this case, that it doesn’t even apply to $(

@Dennis: that doesn’t work because the environment is only set after the processing of the argument list — so ‘grep’ sees the correct value of IFS, but the shell that is processing the argument list does not.

cat listOfFiles.txt |tr '\n' '\0' |xargs -0 grep -li 'regex' 

The -0 option on xargs tells xargs to use a null character rather than white space as a filename terminator. The tr command converts the incoming newlines to a null character.

Читайте также:  Linux running on windows machine

This meets the OP’s requirement that grep not be invoked multiple times. It has been my experience that for a large number of files avoiding the multiple invocations of grep improves performance considerably.

This scheme also avoids a bug in the OP’s original method because his scheme will break where listOfFiles.txt contains a number of files that would exceed the buffer size for the commands. xargs knows about the maximum command size and will invoke grep multiple times to avoid that problem.

A related problem with using xargs and grep is that grep will prefix the output with the filename when invoked with multiple files. Because xargs invokes grep with multiple files one will receive output with the filename prefixed, but not for the case of one file in listOfFiles.txt or the case of multiple invocations where the last invocation contains one filename. To achieve consistent output add /dev/null to the grep command:

cat listOfFiles.txt |tr '\n' '\0' |xargs -0 grep -i 'regex' /dev/null 

Note that was not an issue for the OP because he was using the -l option on grep; however it is likely to be an issue for others.

Источник

How to Tackle Filenames With Spaces in Linux

Spaces in the file names could be tricky, specially for new Linux users. Learn how to deal with them.

The one thing you’ll notice that files in Linux usually do not contain names. Your teacher or colleague use underscore instead of spaces in file and directory names.

It’s not that you cannot use spaces in file names in Linux terminal. It’s just that it creates additional pain and that’s why you should avoid it wherever possible.

Why? Let me show that with examples. You know the generic syntax for Linux commands:

command [options] argument1 argument2

In here, the arguments are separated by spaces. If you try to use filenames with spaces directly, it will be treated as separate arguments rather than just one argument.

Spaces in file name create problem in Linux

In the above screenshot, when I try to use cat agatha books command, it doesn’t understand that agatha books is a single argument. It treats agatha and books as different filenames.

How do you deal with spaces in filename, then? There are two ways:

Wrap the entire filename between quotes:

Escape every space using backslash key:

Tab completion often works with spaces as well. Your terminal may show the file name with space escaped with backslash if you press tab key for the filename.

Read a file with spaces in filename

To use a filename with spaces in it, you can wrap it in quotes like this:

cat "file name with spaces"

You may also escape every space with backslash but it is more work and more confusing than the previous method:

cat file\ name\ with\ spaces

Basically, you put a \ before every space in the filename.

You could also use single quotes instead of double quotes.

cat 'file name with spaces'

Read files with spaces in their names

Single quotes ignore any special characters. Double quotes ignores all except $, back quotes and baclslashes. More on it in some other tutorial.

Читайте также:  Skillbox системный администратор linux

Create a file with space in filename

Now, you need to type space in terminal to create the filename here. Use backslash or quotes again.

Similar to the previous section, you can create new files with spaces in the filename using quotes:

touch "file name with spaces"
touch file\ name\ with\ spaces

Creating new files with space in their names in Linux

Dealing with space in folder name

You can create a directory with space in its name the same way you create a file.

Now, if you want to switch to this directory, you’ll have a path with spaces.

But that should not be a problem for you anymore. To cd into a directory with space, use quotes or backslash again.

Basically, whenever you have to deal with spaces in names, you use quotes or backslash keys.

Suppose you have to copy a file my file from this new dir . Here’s what you can do:

Dealing with folders with spaces in their name in Linux

Now it starts to get confusing a bit, right? There are backslashes and forward slashes. It could intimidate a new user or even a seasoned one if there are way too many of those slashes.

It gets even messier when there are backslashes in the filename. Then you’ll be seeing double backsplashes.

This is the reason why you should try and avoid using spaces or other special characters in file names. To separate the words in a file name, use underscore.

touch a_very_long_file_name_with_too_many_words

This makes the filenames easier to read and you won’t have to make the extra effort to deal with those spaces in the filenames.

Источник

How to access files/directories with spaces in the name? [duplicate]

Through terminal I can’t access files or directories with a spaces in their names. The cd command says no such file or directory . Is there any way to do it or should I rename all files with spaces?

2 Answers 2

To access a directory having space in between the name use \ to access it. You can also use Tab button to auto completion of name.

guru@guru-Aspire-5738:~$ cd /media/Data/My\ Data/ guru@guru-Aspire-5738:/media/Data/My Data$. 

To to use files with spaces you can either use the escape character or youse the double quotes.

\ is called escape character, used to not expansion of space, so now bash read the space as part of file name.

Now to rename files, it’s so easy to rename all files with spaces and replace space with underscore:

for file in * ; do mv "$f" "$" ; done 

look at answer here there is a script to rename all files and dirs recursively.

The script is:(All rights go to its owner)

#!/bin/bash # set -o xtrace # uncomment for debugging declare weirdchars=" &\'" function normalise_and_rename() < declare -a list=("$") for fileordir in "$"; do newname="$]/_>" [[ ! -a "$newname" ]] && \ mv "$fileordir" "$newname" || \ echo "Skipping existing file, $newname." done > declare -a dirs files while IFS= read -r -d '' dir; do dirs+=("$dir") done < <(find -type d -print0 | sort -z) normalise_and_rename dirs[@] while IFS= read -r -d '' file; do files+=("$file") done < <(find -type f -print0 | sort -z) normalise_and_rename files[@] 

Источник

Handling filenames with spaces in Linux

It’s normal that we make files and directories (or we can say folders) in our machines to keep them organized, so when we need to, we can easily search for them. Sometimes we save them with the names having spaces, for example, we save a file with the name “my file” now in this case the Linux terminal will create an error. Can files not be saved with spaces in Linux? Yes! we can but they will be accessed differently in the terminal.

Читайте также:  Изменить mac адрес сетевой карты linux

This write-up is focussing on what errors we face while accessing files and directories with space in their names and how to avoid such errors.

How to create a file with spaces in its name in Linux

To understand how to reference a filename with spaces in Linux, we will consider an example. First, we will open the terminal.

Then create a file with the name “my file” by using the touch command:

Now see the file is being created or not by using the “ls” command. We observed that instead of one, two files have been created, one with “my” and the second with the “file” name.

To use spaces in the name we use either quotes (‘ ’) or escape sequence (\). Now we again make another file using (‘ ’) and another using (\).

touch 'my file' touch test\ file 

Now again use the “ls” command to view files.

Files have been created. Let’s check if we get the same errors in the creation of a directory using space or not. We will create a directory using space with the mkdir command.

We will view whether the directory has been created or not using the “ls ” command. It created two directories instead of one.

We can rectify this in the same way as we did in the file creation method by using (‘ ‘) or (\). Again make a directory using this (‘ ‘) or (\).

Now we will check out the results.

How to reference filename with spaces in Linux

So we can see that the directory has been created according to our requirements. Now if we want to view the contents of the file, we simply use cat and file name with spaces; it will give us an error that the directory is not available.

We should use “\”. For example, we want to view the contents of a test file by using the cat command.

The file is empty so it displays no results but the command runs successfully. We can also open files by using apostrophes (‘ ’) or quotations (“ ”) as:

cat "test file" [OR] cat 'test file' 

Delete filenames with Spaces in Linux

Similarly, you can also delete a file and directory with space in their name by using apostrophes ( ‘ ’ ), quotation marks (“ ”) or escape sequence ( \ ).

Similarly, you can delete a directory with spaces in the name.

Conclusion

We create files and directories, without bothering to focus on the names that can have spaces. The Linux terminal treated files and folders differently that have spaces in their names. So this article solved the problem. If we want to name a file or directory with spaces we can do it by using apostrophes ( ‘ ’ ) , quotation marks (“ ”) or escape sequence ( \ ).

Источник

Оцените статью
Adblock
detector