Find files with spaces in the bash
Use find command with a space between two wildcards. It will match files with single or multiple spaces. "find ." will find all files in current folder and all the sub-folders. "-type f" will only look for files and not folders.
find . -type f -name "* *"
EDIT
To replace the spaces with underscores, try this
find . -type f -name "* *" | while read file; do mv "$file" ${file// /_}; done
How do I store file names that have spaces in a variable in shell script
If the filenames don't contain newlines
grep .txt MYFILES.txt | while IFS= read -r file ; do
echo "$file"
done
File names with spaces in BASH
First, you don't need ls
. By using ls
in backtics, you implicitly make bash parse a string into a list, which splits by whitespaces. Instead, make bash generate the list and separate it without such quirks:
Also, you need to enclose all $i
usages into quotes, to make bash substitute it as a whole, not as a string split to separate words.
Here's the script that demonstrates both ideas:
for i in *.jpg ; do
echo "$i";
done
How to make bash script take file names with spaces?
You need double quotes inside the backticks. The outer set isn't sufficient.
echo "first line is `head -1 "$file_name"`"
Also, do not put backslashes in the file name, since it's already quoted. Quotes or backslashes, but not both.
myfiles=("file with spaces.csv")
myfiles=(file\ with\ spaces.csv)
Linux Scripting with Spaces in Filenames
So after reading through the commentary, we decided that although it may not be the right answer for every scenario, the right answer for this specific scenario was to extract the pieces manually.
Because we are building this for a pre-built script passing to it, and we aren't updating that script any time soon, we can accept with certainty that this script will always receive a -i, -o, and -e flag, and there will be spaces between them, which causes all the pieces passed in to be stored in different variables in $*
.
And we can assume that the text after a flag is the response to the flag, until another flag is referenced. This leaves us 3 scenarios:
- The variable contains one of the flags
- The variable contains the first piece of a parameter immediately after the flag
- The variable contains part 2+ of a parameter, and the space in the name was interpreted as a split, and needs to be reinserted.
One of the other issues I kept running into was trying to get string literals to equate to variables in my IF statements. To resolve that issue, I pre-stored all relevant data in array variables, so I could test $variable == $otherVariable.
Although I don't expect it to change, we also handled what to do if the three flags appear in a different order than we anticipate (Our assumption was that they list as i,o,e... but we can't see excatly what is passed). The parameters are dumped into an array in the order they were read in, and a parallel array tracks whether the items in slots 0,1,2 relate to i,o,e.
The final result still has one flaw: if there is more than one consecutive space in the filename, the whitespace is trimmed before processing, and I can only account for one space. But saying as we processed over 4000 files before encountering one with a space, I find it unlikely with the naming conventions that we would encounter something with more than one space.
At that point, we would have to be stepping in for a rare intervention anyways.
Final code change is as follows:
#!/bin/bash
IFS='|'
position=-1
ioeArray=("" "" "")
previous=""
flagArr=("-i" "-o" "-e" " ")
ioePattern=(0 1 2)
#echo "for loop:"
for i in $*; do
#printf "%s\n" "$i"
if [ "$i" == "${flagArr[0]}" ] || [ "$i" == "${flagArr[1]}" ] || [ "$i" == "${flagArr[2]}" ]; then
((position += 1));
previous=$i;
case "$i" in
"${flagArr[0]}")
ioePattern[$position]=0
;;
"${flagArr[1]}")
ioePattern[$position]=1
;;
"${flagArr[2]}")
ioePattern[$position]=2
;;
esac
continue;
fi
if [[ $previous == "-"* ]]; then
ioeArray[$position]=${ioeArray[$position]}$i;
else
ioeArray[$position]=${ioeArray[$position]}" "$i;
fi
previous=$i;
done
echo "extracting (${ioeArray[${ioePattern[0]}]}) to (${ioeArray[${ioePattern[1]}]}) with (${ioeArray[${ioePattern[2]}]}) encoding."
inputfile=""${ioeArray[${ioePattern[0]}]}"";
outputfile=""${ioeArray[${ioePattern[1]}]}"";
encoding=""${ioeArray[${ioePattern[2]}]}"";
for name in `ls` and filenames with spaces
Just don't use command substitution: use for name in *
.
Bash and filenames with spaces
Try this:
(IFS=$'\n'; grep -li 'regex' $(<listOfFiles.txt))
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 <<<"$IFS"
.
Enclosing the script in parenthesis starts a subshell so that only commands within the parenthesis are affected by the custom IFS
value.
Related Topics
How to Set Memory Limit for Oom Killer for Chrome
How to Have Simple and Double Quotes in a Scripted Ssh Command
Nginx Redirect Url with Query Strings
How to Convert Yyyymmddhhmmss to a Date Readable by 'Date'
Why Does Printf Overwrite the Ecx Register
View Tabular File Such as CSV from Command Line
Remove a Symlink to a Directory
Differencebetween Buffer and Cache Memory in Linux
How to Get the Start Time of a Long-Running Linux Process
Count Number of Files Within a Directory in Linux
Efficiently Test If a Port Is Open on Linux
How to Automatically Add User Account and Password with a Bash Script
Docker Command Can't Connect to Docker Daemon
How to Find the Java Sdk in Linux After Installing It
How to Monitor the Thread Count of a Process on Linux