Find command to collect the file list having spaces
Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Find command to collect the file list having spaces
Hello Experts,
I wish to list the files using arrays. But the filenames are containing many spaces. How do I correctly collect and list the files.
I wrote following script but it does not seem to escape the white spaces.
Code:
#!/bin/bash
echo "Checking for older files now..." >>/tmp/list
tree_file=(`find /Datafolder/ -type f -ctime +1460 -exec echo '{}' +`)
for i in "${tree_file[@]}"
do
echo Files are "$i" >> /tmp/list
done
After execution the output shows like this,
[QUOTE]
Quote:
Files are /Datafolder/Infos
Files are SZ
Files are 04
Files are 07
Files are Information
Files are Datafolder/BZ
Files are SZ
Files are SZ10
Your problem is the expansion in the 'for i in' line, where the values stored in the variable are exanded to SPACE DELIMITED WORDS!
Instead of looping through a variable, have find do the printing. Check the man page and play with the -printf option and reduce your script to two lines of code.
#!/bin/bash
echo "Checking for older files now..." >>/tmp/list
find /Datafolder/ -type f -ctime +1460 | while read i
do
echo Files are "$i" >> /tmp/list
done
I ran into something like this the other day. grail suggested bash's mapfile function.
Code:
#!/bin/bash
mapfile -t tree <<<"$(find /Datafolder/ -type f -ctime +1460 -print)";
IFS=$'\n';
for i in ${tree[*]}; do
echo Files are "$i" >> /tmp/list;
done;
#!/bin/bash
echo "Checking for older files now..." >>/tmp/list
find /Datafolder/ -type f -ctime +1460 | while read i
do
echo Files are "$i" >> /tmp/list
done
Thanks Ondoho for this code. It works. But the Original script is much more complex and we need to collect the output of find in an array to be able to use it further down the script. So Array is important here.
Thanks Ondoho for this code. It works. But the Original script is much more complex and we need to collect the output of find in an array to be able to use it further down the script. So Array is important here.
It would have been helpful had you mentioned this in the original message.
Using an array for this case is an elegant option. Another is a delimited list, but I like the array better.
It would have been helpful had you mentioned this in the original message.
Using an array for this case is an elegant option. Another is a delimited list, but I like the array better.
Sorry. But with Array we get the mentioned errors. So any suggestion?
Sorry. But with Array we get the mentioned errors. So any suggestion?
In your original script you did NOT use an array. You just captured the find output into a list variable.
The solution by Turbocapitalist uses an array. That solution should serve you well. You can parse over the array as many times as you need.
In your original script you did NOT use an array. You just captured the find output into a list variable.
The solution by Turbocapitalist uses an array. That solution should serve you well. You can parse over the array as many times as you need.
# rpm -qa | grep bash
bash-3.1-24.26.20
# bash -version
GNU bash, version 3.1.17(1)-release (i586-suse-linux)
> mapfile
bash: mapfile: command not found
# which mapfile
which: no mapfile in (/sbin:/usr/sbin:/usr/local/sbin:/opt/gnome/sbin:/root/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/us
$ bash -version
GNU bash, version 5.0.7(1)-release (x86_64-slackware-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
---------------
userx@slack.curry.org:~
$ which mapfile
which: no mapfile in (/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib64/kde4/libexec:/usr/lib64/qt/bin:/usr/lib64/qt5/bin:/home/userx/bin:/sbin:/usr/sbin)
mapfile is built into BASH so it is not going to show as a external program.
spaces too
Code:
$ mapfile -t < <(printf "Line 1\nLine 2\nLine 3\nLine 4\n")
userx@slack.curry.org:~
$ for ((i=0;i<${#MAPFILE[@]};i++)) ; do echo ${MAPFILE[$i]} ; done
Line 1
Line 2
Line 3
Line 4
#!/bin/bash
#creates file and adds first line '>'
echo "Checking for older files now..." > /tmp/list
mapfile -t < <(find /Datafolder/ -type f -ctime +1460)
echo "adding to file..."
for ((i=0;i<${#MAPFILE[@]};i++)) ; do echo ${MAPFILE[$i]} >> /tmp/list ; done
$ bash -version
GNU bash, version 5.0.7(1)-release (x86_64-slackware-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
---------------
userx@slack.curry.org:~
$ which mapfile
which: no mapfile in (/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib64/kde4/libexec:/usr/lib64/qt/bin:/usr/lib64/qt5/bin:/home/userx/bin:/sbin:/usr/sbin)
#./findfiles.sh
line 19: mapfile: command not found
BUTT's... change distros, j/k
Quote:
Thanks Ondoho for this code. It works. But the Original script is much more complex and we need to collect the output of find in an array to be able to use it further down the script. So Array is important here.
try this
Code:
#!/bin/bash
#declare array for later processing
fileArray=()
#split it to see it starting
echo "finding files..." | tee -a /tmp/MyList
while read f
do
#fill array
fileArray+=("$f")
#want it in a file and output to screen too?
#echo "$f" | tee -a /tmp/MyList
#just put it in a file too?
#echo "$f" >> /tmp/MyList
done <<<$(find /Datafolder/ -type f -ctime +1460)
echo "here is the array filled"
printf '%s\n' "${fileArray[@]}"
echo "amount"
echo "${#fileArray[@]}"
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.