- How to Read a Filename with Spaces in Linux
- 1) Creating file names with spaces
- 2) Read a File with spaces in filename
- 3) Creating directory names with spaces
- 4) Navigating to a directory with spaces in the directory name
- 5) Copying a directory with spaces in the directory name
- BASH Shell: For Loop File Names With Spaces
- Set $IFS variable
- More examples using $IFS and while loop
- Using old good find command to process file names
- Processing filenames using an array
- Playing mp3s with spaces in file names
How to Read a Filename with Spaces in Linux
It’s not very common in Linux to handle filename with spaces but sometimes files copied or mounted from windows would end up with spaces.
While it is not recommended to have file names with spaces, let discuss how to manage filename with spaces in a Linux system.
We will cover how to create, read and copy a file which has spaces in their filename.
1) Creating file names with spaces
To create files with spaces in file names, run the command as shown
For example, to create a file called ‘linoxide docs‘ use the syntax below
Output
If you want to view such a file with space in the file name, use the same principle of enclosing the file names inside the quotation marks.
2) Read a File with spaces in filename
You can use ‘cat’ command or open the document using your preferred text editor such as vim, nano or gedit.
Alternatively, you can use the syntax below
Let’s add some text to the ‘linoxide docs’ file
To view the file execute the command below
Output
3) Creating directory names with spaces
To create directory names with space in between use the syntax below
Please note the space after the backslash
For example, to create a directory called ‘linoxide files‘ run
Output
4) Navigating to a directory with spaces in the directory name
To navigate to a directory with spaces in its directory name, use the syntax below
To navigate to the directory ‘linoxide files’ execute the command below
5) Copying a directory with spaces in the directory name
To copy a directory with spaces in its directory name to a different location use the syntax below
For example to copy ‘linoxide files’ to /home/james path execute
Hope this article explained well on how to manage filename with spaces. Thanks for taking the time to read this article and please leave your comments.
Источник
BASH Shell: For Loop File Names With Spaces
BASH for loop works nicely under UNIX / Linux / Windows and OS X while working on set of files. However, if you try to process a for loop on file name with spaces in them you are going to have some problem. For loop uses $IFS variable to determine what the field separators are. By default $IFS is set to the space character. There are multiple solutions to this problem.
Set $IFS variable
Try it as follows:
More examples using $IFS and while loop
Now you know that if the field delimiters are not whitespace, you can set IFS. For example, while loop can be used to get all fields from /etc/passwd file:
Using old good find command to process file names
To process the output of find with a command, try as follows:
Try to copy files to /tmp with spaces in a filename using find command and shell pipes:
Processing filenames using an array
Sometimes you need read a file into an array as one array element per line. Following script will read file names into an array and you can process each file using for loop. This is useful for complex tasks:
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
Playing mp3s with spaces in file names
Place following code in your
Keep list of all mp3s in a text file such as follows (
To play just type:
$ mp3 eng.mp3.txt
Category | List of Unix and Linux commands |
---|---|
Documentation | help • mandb • man • pinfo |
Disk space analyzers | df • duf • ncdu • pydf |
File Management | cat • cp • less • mkdir • more • tree |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Linux Desktop Apps | Skype • Spotify • VLC 3 |
Modern utilities | bat • exa |
Network Utilities | NetHogs • dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • glances • gtop • jobs • killall • kill • pidof • pstree • pwdx • time • vtop |
Searching | ag • grep • whereis • which |
Shell builtins | compgen • echo • printf |
Text processing | cut • rev |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Comments on this entry are closed.
Hi, I don’t fully understand how this…
BASH for loop works nicely under UNIX / Linux / Windows and OS X
works nicely under Windows…
Oh! btw, thank you.
Install bash and your are done!
For the shell equivalent of python’s splitlines, I always did it like this:
Thanks really so much,
It’s so useful and I think it’d save me a lot of time and help me do better shell coding..
This is a great blog!
Instead of using following:
Never had problems with it. A filename can impossible contain newline-chars, or am I wrong?
Best regards,
Benjamin Schmidt
File names can contain newline characters.
Gnome for example displays them correctly. Couldn’t manage to create such a file in Gnome. I tested creation in C and Python iirc.
In bash you can create a file with a newline in the name using, e.g:
Thanks for sharing your code and ideas.
i’d love to play music with mplayer… through cli
let say that i have song/music folder with many directory inside, how i can play with mplayer with single command. Actually i have one bash script, but i got trouble when facing white space… mplayer wouldn’t play the file
[songRequest.sh]
for i in ` find -name “*mp3″`
do
mplayer $i
done
any help will be appreciated
> A filename can impossible contain newline-chars, or am I wrong?
A filename can contain newlines. It can contain any character except a slash (/) or an ASCII NUL (0x0).
# use for loop read all filenames
> for (( i=0; i do
> echo “$
> done
If all you want to do is print the contents of the array:
To loop through them, use:
your script just work on one file… then mplayer killed immediately.
yeah just playing one file only(there are many left).
on playing progress i can’t get control of mplayer, even i can’t turn up/down volume, go to the next song, etc.
all i can do is Ctrl+C
I guess you can try
mplayer *.mp3
Or send all files to .playlist.txt
ls -1 > .playlist.txt
mplayer -playlist .playlist.txt
All this information is very useful, but I think that needing it is sympton: ¿shouldn’t you use another language instead?
Nice post, though
“All this information is very useful, but I think that needing it is sympton: ¿shouldn’t you use another language instead?”
Why? It’s straightforward shell scripting.
opendir(DIR, “.”) or die(“Error opening directory”);
my @readFiles = readdir(DIR);
foreach (@readFiles) <
…
I don’t think there is a need to reset the IFS variable, all you really need to do to avoid problems with word splitting is to put the variables that appear in the loop body in double quotes (I find this to be a good default habit). Once in double quotes the shell will consider whatever the variable expands to as a single argument and pass it to the program as such.
For example:
for i in *.mp3; do rm “$i”; done
mhernandez: Its not a problem with the shell, its just how it works, the bash shell is based on word splitting.
This doesn’t seem to work for me. I’m wondering what I’m doing wrong….
it doesn’t work as I would have expected.
You can reset the IFS with
unset IFS
this way, you do not need to save the state and then recall it from a variable.
Kyle is correct. No need to mess w/ your IFS var.
Your 2nd example is problematic in a very subtle way
does not set the variable ‘FILES’ to the names of all the files in /data, it sets it to ‘/data/*’. You can see this w/:
declare -p FILES
A very useful technique in all this, is to employ the ‘set’ builtin:
This lets you scoop up a file list (w/ nasty names and all), and then move somewhere else to process them.
i am doing a project in unix shell scripting.
so my project have messages to be displayed. my problem is that how to add a beep sound to the messages …can any help me to include that also with the coding??pls..its very urgent…i dont know the shell codings…its for my project
Chris F.A. Johnson has it right on the nose.
use a quoted @-array: DoXuS Jul 21, 2009 @ 11:51
Thanks man, my code is now only 40 lines long, not 136 like before xD^^
nice blog
mp3() <
local o=$IFS
IFS=$(echo -en “nb”)
/usr/bin/beep-media-player “$(cat $@)” &
IFS=o
>
“$(cat $@)” if you use this I think the IFS down work …
I think you want $(cat “$@”)
Thank you! I found this post most useful.
Instead of telling echo to print a char for new line and (probably) bell and then *not* to print a new line, one can just use echo’s default new line output 🙂
Thanks for your share!
Why “IFS=`echo`”? Command substitution is slow (and unnecessary).
Amazing! Your notation for creating an array from:
> fileArray=($(find $DIR -type f))
is stunning! Thanks for the excellent writeup.
I just use as following
with double quotes
[code]
for m in “`ls`”; do echo “$m” ; done
[/code]
for m in «`ls`»; do echo «$m» ; done
The for command will only see one argument.
You’ll see that it only goes through the loop once.
You don’t need a loop for that, and you don’t need ls :
excellent post. exactly what i was looking for. i had been facing this space-field-seperator problem for quite a sometime today. had tried many options to circumvent it, but in vain. will try this $IFS approach now.
thanks a lot for sharing.
My favorite solution, though it can theoretically overmatch:
find . | sed -e “s/ /?/g”
ls | sed -e “s/ /?/g”
Then you can do things like greps, for loops, whatever equally well:
grep hello $(ls | sed -e “s/ /?/g”)
for i in $(find . | sed -e “s/ /?/g) do; ls -l “$i”; done
“grep hello $(ls | sed -e “s/ /?/gâ€)”
You don’t need sed or ls; use filename expansion:
“for i in $(find . | sed -e “s/ /?/g) do; ls -l “$iâ€; done”
That will fail if any filenames contain whitespace.
It is also extremely inefficient to call ls in a loop.
Great post! It has been very useful for me 😀
Hey, thanks for this! I never did much bash scripting and was trying to figure out how to parse an array from a bash RC file into a Perl variable. I started out writing a long parser hack, but trying to support array entries with spaces was a big headache. Then thought maybe bash should do the work instead, and your examples helped a lot. Here’s a one-liner bash script that’s run using the Perl `backtick` operator.
$path is the RC file, and $var is the array variable. BASH variables must be escaped, but PERL
variables must not, and new-line chars have to be added so bash is happy with the string.
First step is to source the RC file, and next get the length of the array.
$list = `. $path; L=$<#$[@]>n for (( i=0; i Kelvin Nicholson Aug 25, 2010 @ 21:40
Fixed my little script! Cheers for posting this – always nice to learn something new.
Trying to get the following to work. If I cut and paste the eventual contents of $directoryFiles EITHER in the bash script OR on the command line, it works perfectly. If I try to get it to do it directly in the script, it fails with:
tar –all the file names– : Cannot stat: No such file or directory
I”ve tried about every expansion or quoting that I can think of for the $direcotryFiles variable.
Источник