How can I store the “find” command results as an array in BashStore the output of find command in an arrayShell Script for finding files with certain patterns in a directory?Is possible to store “find” output in a bash variable for further elaboration of each line?How do you send the output of ls to mv?How to create tar for files older than 7 days using linux shell scriptingSetting IFS to null byte does not split lines correctly in command lineHow do I store the output from a find command in an array? + bashFind files in current directory sorted by modified time and store result in an arrayBASH: How would I modify this script to allow file names with spaces?How can I sort filenames within multiple directories into one sequential and numerically ascending array/list?How to check if a string contains a substring in BashHow do I check if an array includes an object in JavaScript?How to append something to an array?How to check if a program exists from a Bash script?How do I tell if a regular file does not exist in Bash?How do you check if a variable is an array in JavaScript?How to concatenate string variables in BashHow to check if an object is an array?How do I remove a particular element from an array in JavaScript?How do I find all files containing specific text on Linux?
What is the difference between a premise and an assumption in logic?
The sound of thunder's like a whip
What professions would a medieval village with a population of 100 need?
Can you be convicted for being a murderer twice?
Sleeping solo in a double sleeping bag
Does C++20 mandate source code being stored in files?
Is there a SubImageApply?
The teacher logged me in as administrator for doing a short task, is the whole system now compromised?
Is "stainless" a bulk or a surface property of stainless steel?
Are illustrations in novels frowned upon?
A second course in the representation theory
Why doesn't mathematics collapse down, even though humans quite often make mistakes in their proofs?
Would combining A* with a flocking algorithm be too performance-heavy?
How did Apollo 15's depressurization work?
Does adding the 'precise' tag to daggers break anything?
Why were movies shot on film shot at 24 frames per second?
Does Swashbuckler's Fancy Footwork apply if the attack was made with Booming Blade?
In an emergency, how do I find and share my position?
What does it mean to have a subnet mask /32?
Is there such a thing as too inconvenient?
How to setup a teletype to a unix shell
Ask for a paid taxi in order to arrive as early as possible for an interview within the city
Potential new partner angry about first collaboration - how to answer email to close up this encounter in a graceful manner
Are there reliable, formulaic ways to form chords on the guitar?
How can I store the “find” command results as an array in Bash
Store the output of find command in an arrayShell Script for finding files with certain patterns in a directory?Is possible to store “find” output in a bash variable for further elaboration of each line?How do you send the output of ls to mv?How to create tar for files older than 7 days using linux shell scriptingSetting IFS to null byte does not split lines correctly in command lineHow do I store the output from a find command in an array? + bashFind files in current directory sorted by modified time and store result in an arrayBASH: How would I modify this script to allow file names with spaces?How can I sort filenames within multiple directories into one sequential and numerically ascending array/list?How to check if a string contains a substring in BashHow do I check if an array includes an object in JavaScript?How to append something to an array?How to check if a program exists from a Bash script?How do I tell if a regular file does not exist in Bash?How do you check if a variable is an array in JavaScript?How to concatenate string variables in BashHow to check if an object is an array?How do I remove a particular element from an array in JavaScript?How do I find all files containing specific text on Linux?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I am trying to save the result from find
as arrays.
Here is my code:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=`find . -name $input`
len=$#array[*]
echo "found : $len"
i=0
while [ $i -lt $len ]
do
echo $array[$i]
let i++
done
I get 2 .txt files under current directory.
So I expect '2' as result of $len
. However, it prints 1.
The reason is that it takes all result of find
as one elements.
How can I fix this?
P.S
I found several solutions on StackOverFlow about a similar problem. However, they are a little bit different so I can't apply in my case. I need to store the results in a variable before the loop. Thanks again.
arrays bash variables find
add a comment |
I am trying to save the result from find
as arrays.
Here is my code:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=`find . -name $input`
len=$#array[*]
echo "found : $len"
i=0
while [ $i -lt $len ]
do
echo $array[$i]
let i++
done
I get 2 .txt files under current directory.
So I expect '2' as result of $len
. However, it prints 1.
The reason is that it takes all result of find
as one elements.
How can I fix this?
P.S
I found several solutions on StackOverFlow about a similar problem. However, they are a little bit different so I can't apply in my case. I need to store the results in a variable before the loop. Thanks again.
arrays bash variables find
add a comment |
I am trying to save the result from find
as arrays.
Here is my code:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=`find . -name $input`
len=$#array[*]
echo "found : $len"
i=0
while [ $i -lt $len ]
do
echo $array[$i]
let i++
done
I get 2 .txt files under current directory.
So I expect '2' as result of $len
. However, it prints 1.
The reason is that it takes all result of find
as one elements.
How can I fix this?
P.S
I found several solutions on StackOverFlow about a similar problem. However, they are a little bit different so I can't apply in my case. I need to store the results in a variable before the loop. Thanks again.
arrays bash variables find
I am trying to save the result from find
as arrays.
Here is my code:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=`find . -name $input`
len=$#array[*]
echo "found : $len"
i=0
while [ $i -lt $len ]
do
echo $array[$i]
let i++
done
I get 2 .txt files under current directory.
So I expect '2' as result of $len
. However, it prints 1.
The reason is that it takes all result of find
as one elements.
How can I fix this?
P.S
I found several solutions on StackOverFlow about a similar problem. However, they are a little bit different so I can't apply in my case. I need to store the results in a variable before the loop. Thanks again.
arrays bash variables find
arrays bash variables find
edited Mar 10 at 10:11
Al.G.
3,0285 gold badges25 silver badges45 bronze badges
3,0285 gold badges25 silver badges45 bronze badges
asked Apr 29 '14 at 6:07
Juneyoung OhJuneyoung Oh
2,79810 gold badges42 silver badges90 bronze badges
2,79810 gold badges42 silver badges90 bronze badges
add a comment |
add a comment |
7 Answers
7
active
oldest
votes
Here is one solution for getting the output of find
into a bash
array:
array=()
while IFS= read -r -d $''; do
array+=("$REPLY")
done < <(find . -name "$input" -print0)
This is tricky because, in general, file names can have spaces, new lines, and other script-hostile characters. The only way to use find
and have the file names safely separated from each other is to use -print0
which prints the file names separated with a null character. This would not be much of an inconvenience if bash's readarray
/mapfile
functions supported null-separated strings but they don't. Bash's read
does and that leads us to the loop above.
How it works
The first line creates an empty array:
array=()
Every time that the
read
statement is executed, a null-separated file name is read from standard input. The-r
option tellsread
to leave backslash characters alone. The-d $''
tellsread
that the input will be null-separated. Since we omit the name toread
, the shell puts the input into the default name:REPLY
.The
array+=("$REPLY")
statement appends the new file name to the arrayarray
.The final line combines redirection and command substitution to provide the output of
find
to the standard input of thewhile
loop.
Why use process substitution?
If we didn't use process substitution, the loop could be written as:
array=()
find . -name "$input" -print0 >tmpfile
while IFS= read -r -d $''; do
array+=("$REPLY")
done <tmpfile
rm -f tmpfile
In the above the output of find
is stored in a temporary file and that file is used as standard input to the while loop. The idea of process substitution is to make such temporary files unnecessary. So, instead of having the while
loop get its stdin from tmpfile
, we can have it get its stdin from <(find . -name $input -print0)
.
Process substitution is widely useful. In many places where a command wants to read from a file, you can specify process substitution, <(...)
, instead of a file name. There is an analogous form, >(...)
, that can be used in place of a file name where the command wants to write to the file.
Like arrays, process substitution is a feature of bash and other advanced shells. It is not part of the POSIX standard.
Additional notes
The following command creates a shell variable, not a shell array:
array=`find . -name "$input"`
If you wanted to create an array, you would need to put parens around the output of find. So, naively, one could:
array=(`find . -name "$input"`) # don't do this
The problem is that the shell performs word splitting on the results of find
so that the elements of the array are not guaranteed to be what you want.
Awesome! Thanks. But could you explain little more about last line? I mean redirection part. At first, I write "<<" and it show syntax error on "(". After several tries, I just copy your code to mine and it works. what is the meaning of '<' in last line?
– Juneyoung Oh
Apr 29 '14 at 8:14
^^ checkbash
manual for process redirection section.
– anishsane
Apr 29 '14 at 8:38
1
@JuneyoungOh Glad it helped. I added a section of process substitution.
– John1024
Apr 29 '14 at 17:52
2
@Rockallite That is a good observation but incomplete. While it is true that we don't split into multiple words, we still needIFS=
to avoid removal of whitespace from the beginnings or ends of the input lines. You can test this easily by comparing the output ofread var <<<' abc '; echo ">$var<"
with the output ofIFS= read var <<<' abc '; echo ">$var<"
. In the former case, the spaces before and afterabc
are removed. In the latter, they aren't. File names that begin or end with whitespace may be unusual but, it they exist, we want them processed correctly.
– John1024
Feb 24 '17 at 2:20
1
@jacderida Good point. I added a sentence to explainREPLY
.
– John1024
Aug 17 '17 at 20:33
|
show 11 more comments
If you are using bash
4 or later, you can replace your use of find
with
shopt -s globstar nullglob
array=( **/*"$input"* )
The **
pattern enabled by globstar
matches 0 or more directories, allowing the pattern to match to an arbitrary depth in the current directory. Without the nullglob
option, the pattern (after parameter expansion) is treated literally, so with no matches you would have an array with a single string rather than an empty array.
Add the dotglob
option to the first line as well if you want to traverse hidden directories (like .ssh
) and match hidden files (like .bashrc
) as well.
3
Maybenullglob
too…
– kojiro
Apr 29 '14 at 17:59
Yeah, I always forget that.
– chepner
Apr 29 '14 at 18:00
4
Note that this will not include the hidden files and directories, unlessdotglob
is set (this may or may not be wanted, but it's worth mentioning too).
– gniourf_gniourf
Apr 29 '14 at 18:03
Soooo many options :)
– chepner
Apr 29 '14 at 18:06
add a comment |
Bash 4.4 introduced a -d
option to readarray
/mapfile
, so this can now be solved with
readarray -d '' array < <(find . -name "$input" -print0)
for a method that works with arbitrary filenames including blanks, newlines, and globbing characters.
From the manual (omitting other options):
mapfile [-d delim] [array]
-d
The first character ofdelim
is used to terminate each input line, rather than newline. Ifdelim
is the empty string,mapfile
will terminate a line when it reads a NUL character.
And readarray
is just a synonym of mapfile
.
add a comment |
you can try something like
array=(`find . -type f | sort -r | head -2`)
, and in order to print the array values , you can try something like echo "$array[*]"
5
Breaks if there are filenames with spaces or glob characters.
– gniourf_gniourf
Dec 25 '17 at 9:13
add a comment |
In bash, $(<any_shell_cmd>)
helps to run a command and capture the output. Passing this to IFS
with n
as delimiter helps to convert that to an array.
IFS='n' read -r -a txt_files <<< $(find /path/to/dir -name "*.txt")
This will get only the first file of the results offind
into the array.
– Benjamin W.
Mar 12 at 21:17
add a comment |
You could do like this:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=(`find . -name '*'$input'*'`)
for i in "$array[@]"
do :
echo $i
done
2
There is a problem, if the file names have a space...
– anishsane
Apr 29 '14 at 7:11
Thanks. a lot. But as @anishsane pointed, empty spaces in filename should be considered in my program. Anyway Thanks!
– Juneyoung Oh
Apr 29 '14 at 8:15
add a comment |
For me, this worked fine on cygwin:
declare -a names=$(echo "("; find <path> <other options> -printf '"%p" '; echo ")")
for nm in "$names[@]"
do
echo "$nm"
done
This works with spaces, but not with double quotes (") in the directory names (which aren't allowed in a Windows environment anyway).
Beware the space in the -printf option.
its not working for me on mac
– To Kra
Dec 28 '16 at 14:44
2
Broken and dangerous: will not handle quotes, and is subject to arbitrary code injection. DO NOT USE.
– gniourf_gniourf
Dec 25 '17 at 9:14
1
It looks like someone flagged this post for deletion. "It is wrong" is not a reason for deletion on SO. The user made an attempt to answer, it is on topic, and meets the criteria for answers. The downvote button is used to measure usefulness and correctness, not the deletion button.
– Joe Frambach
Mar 14 '18 at 21:27
1
As gniourf pointed out, it's not for environments where others enter the options on your system, e.g. web pages. But not everybody program for that environment. I used it for renaming files in directories.
– R Risack
Jan 29 at 10:53
add a comment |
protected by gniourf_gniourf Dec 25 '17 at 8:56
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here is one solution for getting the output of find
into a bash
array:
array=()
while IFS= read -r -d $''; do
array+=("$REPLY")
done < <(find . -name "$input" -print0)
This is tricky because, in general, file names can have spaces, new lines, and other script-hostile characters. The only way to use find
and have the file names safely separated from each other is to use -print0
which prints the file names separated with a null character. This would not be much of an inconvenience if bash's readarray
/mapfile
functions supported null-separated strings but they don't. Bash's read
does and that leads us to the loop above.
How it works
The first line creates an empty array:
array=()
Every time that the
read
statement is executed, a null-separated file name is read from standard input. The-r
option tellsread
to leave backslash characters alone. The-d $''
tellsread
that the input will be null-separated. Since we omit the name toread
, the shell puts the input into the default name:REPLY
.The
array+=("$REPLY")
statement appends the new file name to the arrayarray
.The final line combines redirection and command substitution to provide the output of
find
to the standard input of thewhile
loop.
Why use process substitution?
If we didn't use process substitution, the loop could be written as:
array=()
find . -name "$input" -print0 >tmpfile
while IFS= read -r -d $''; do
array+=("$REPLY")
done <tmpfile
rm -f tmpfile
In the above the output of find
is stored in a temporary file and that file is used as standard input to the while loop. The idea of process substitution is to make such temporary files unnecessary. So, instead of having the while
loop get its stdin from tmpfile
, we can have it get its stdin from <(find . -name $input -print0)
.
Process substitution is widely useful. In many places where a command wants to read from a file, you can specify process substitution, <(...)
, instead of a file name. There is an analogous form, >(...)
, that can be used in place of a file name where the command wants to write to the file.
Like arrays, process substitution is a feature of bash and other advanced shells. It is not part of the POSIX standard.
Additional notes
The following command creates a shell variable, not a shell array:
array=`find . -name "$input"`
If you wanted to create an array, you would need to put parens around the output of find. So, naively, one could:
array=(`find . -name "$input"`) # don't do this
The problem is that the shell performs word splitting on the results of find
so that the elements of the array are not guaranteed to be what you want.
Awesome! Thanks. But could you explain little more about last line? I mean redirection part. At first, I write "<<" and it show syntax error on "(". After several tries, I just copy your code to mine and it works. what is the meaning of '<' in last line?
– Juneyoung Oh
Apr 29 '14 at 8:14
^^ checkbash
manual for process redirection section.
– anishsane
Apr 29 '14 at 8:38
1
@JuneyoungOh Glad it helped. I added a section of process substitution.
– John1024
Apr 29 '14 at 17:52
2
@Rockallite That is a good observation but incomplete. While it is true that we don't split into multiple words, we still needIFS=
to avoid removal of whitespace from the beginnings or ends of the input lines. You can test this easily by comparing the output ofread var <<<' abc '; echo ">$var<"
with the output ofIFS= read var <<<' abc '; echo ">$var<"
. In the former case, the spaces before and afterabc
are removed. In the latter, they aren't. File names that begin or end with whitespace may be unusual but, it they exist, we want them processed correctly.
– John1024
Feb 24 '17 at 2:20
1
@jacderida Good point. I added a sentence to explainREPLY
.
– John1024
Aug 17 '17 at 20:33
|
show 11 more comments
Here is one solution for getting the output of find
into a bash
array:
array=()
while IFS= read -r -d $''; do
array+=("$REPLY")
done < <(find . -name "$input" -print0)
This is tricky because, in general, file names can have spaces, new lines, and other script-hostile characters. The only way to use find
and have the file names safely separated from each other is to use -print0
which prints the file names separated with a null character. This would not be much of an inconvenience if bash's readarray
/mapfile
functions supported null-separated strings but they don't. Bash's read
does and that leads us to the loop above.
How it works
The first line creates an empty array:
array=()
Every time that the
read
statement is executed, a null-separated file name is read from standard input. The-r
option tellsread
to leave backslash characters alone. The-d $''
tellsread
that the input will be null-separated. Since we omit the name toread
, the shell puts the input into the default name:REPLY
.The
array+=("$REPLY")
statement appends the new file name to the arrayarray
.The final line combines redirection and command substitution to provide the output of
find
to the standard input of thewhile
loop.
Why use process substitution?
If we didn't use process substitution, the loop could be written as:
array=()
find . -name "$input" -print0 >tmpfile
while IFS= read -r -d $''; do
array+=("$REPLY")
done <tmpfile
rm -f tmpfile
In the above the output of find
is stored in a temporary file and that file is used as standard input to the while loop. The idea of process substitution is to make such temporary files unnecessary. So, instead of having the while
loop get its stdin from tmpfile
, we can have it get its stdin from <(find . -name $input -print0)
.
Process substitution is widely useful. In many places where a command wants to read from a file, you can specify process substitution, <(...)
, instead of a file name. There is an analogous form, >(...)
, that can be used in place of a file name where the command wants to write to the file.
Like arrays, process substitution is a feature of bash and other advanced shells. It is not part of the POSIX standard.
Additional notes
The following command creates a shell variable, not a shell array:
array=`find . -name "$input"`
If you wanted to create an array, you would need to put parens around the output of find. So, naively, one could:
array=(`find . -name "$input"`) # don't do this
The problem is that the shell performs word splitting on the results of find
so that the elements of the array are not guaranteed to be what you want.
Awesome! Thanks. But could you explain little more about last line? I mean redirection part. At first, I write "<<" and it show syntax error on "(". After several tries, I just copy your code to mine and it works. what is the meaning of '<' in last line?
– Juneyoung Oh
Apr 29 '14 at 8:14
^^ checkbash
manual for process redirection section.
– anishsane
Apr 29 '14 at 8:38
1
@JuneyoungOh Glad it helped. I added a section of process substitution.
– John1024
Apr 29 '14 at 17:52
2
@Rockallite That is a good observation but incomplete. While it is true that we don't split into multiple words, we still needIFS=
to avoid removal of whitespace from the beginnings or ends of the input lines. You can test this easily by comparing the output ofread var <<<' abc '; echo ">$var<"
with the output ofIFS= read var <<<' abc '; echo ">$var<"
. In the former case, the spaces before and afterabc
are removed. In the latter, they aren't. File names that begin or end with whitespace may be unusual but, it they exist, we want them processed correctly.
– John1024
Feb 24 '17 at 2:20
1
@jacderida Good point. I added a sentence to explainREPLY
.
– John1024
Aug 17 '17 at 20:33
|
show 11 more comments
Here is one solution for getting the output of find
into a bash
array:
array=()
while IFS= read -r -d $''; do
array+=("$REPLY")
done < <(find . -name "$input" -print0)
This is tricky because, in general, file names can have spaces, new lines, and other script-hostile characters. The only way to use find
and have the file names safely separated from each other is to use -print0
which prints the file names separated with a null character. This would not be much of an inconvenience if bash's readarray
/mapfile
functions supported null-separated strings but they don't. Bash's read
does and that leads us to the loop above.
How it works
The first line creates an empty array:
array=()
Every time that the
read
statement is executed, a null-separated file name is read from standard input. The-r
option tellsread
to leave backslash characters alone. The-d $''
tellsread
that the input will be null-separated. Since we omit the name toread
, the shell puts the input into the default name:REPLY
.The
array+=("$REPLY")
statement appends the new file name to the arrayarray
.The final line combines redirection and command substitution to provide the output of
find
to the standard input of thewhile
loop.
Why use process substitution?
If we didn't use process substitution, the loop could be written as:
array=()
find . -name "$input" -print0 >tmpfile
while IFS= read -r -d $''; do
array+=("$REPLY")
done <tmpfile
rm -f tmpfile
In the above the output of find
is stored in a temporary file and that file is used as standard input to the while loop. The idea of process substitution is to make such temporary files unnecessary. So, instead of having the while
loop get its stdin from tmpfile
, we can have it get its stdin from <(find . -name $input -print0)
.
Process substitution is widely useful. In many places where a command wants to read from a file, you can specify process substitution, <(...)
, instead of a file name. There is an analogous form, >(...)
, that can be used in place of a file name where the command wants to write to the file.
Like arrays, process substitution is a feature of bash and other advanced shells. It is not part of the POSIX standard.
Additional notes
The following command creates a shell variable, not a shell array:
array=`find . -name "$input"`
If you wanted to create an array, you would need to put parens around the output of find. So, naively, one could:
array=(`find . -name "$input"`) # don't do this
The problem is that the shell performs word splitting on the results of find
so that the elements of the array are not guaranteed to be what you want.
Here is one solution for getting the output of find
into a bash
array:
array=()
while IFS= read -r -d $''; do
array+=("$REPLY")
done < <(find . -name "$input" -print0)
This is tricky because, in general, file names can have spaces, new lines, and other script-hostile characters. The only way to use find
and have the file names safely separated from each other is to use -print0
which prints the file names separated with a null character. This would not be much of an inconvenience if bash's readarray
/mapfile
functions supported null-separated strings but they don't. Bash's read
does and that leads us to the loop above.
How it works
The first line creates an empty array:
array=()
Every time that the
read
statement is executed, a null-separated file name is read from standard input. The-r
option tellsread
to leave backslash characters alone. The-d $''
tellsread
that the input will be null-separated. Since we omit the name toread
, the shell puts the input into the default name:REPLY
.The
array+=("$REPLY")
statement appends the new file name to the arrayarray
.The final line combines redirection and command substitution to provide the output of
find
to the standard input of thewhile
loop.
Why use process substitution?
If we didn't use process substitution, the loop could be written as:
array=()
find . -name "$input" -print0 >tmpfile
while IFS= read -r -d $''; do
array+=("$REPLY")
done <tmpfile
rm -f tmpfile
In the above the output of find
is stored in a temporary file and that file is used as standard input to the while loop. The idea of process substitution is to make such temporary files unnecessary. So, instead of having the while
loop get its stdin from tmpfile
, we can have it get its stdin from <(find . -name $input -print0)
.
Process substitution is widely useful. In many places where a command wants to read from a file, you can specify process substitution, <(...)
, instead of a file name. There is an analogous form, >(...)
, that can be used in place of a file name where the command wants to write to the file.
Like arrays, process substitution is a feature of bash and other advanced shells. It is not part of the POSIX standard.
Additional notes
The following command creates a shell variable, not a shell array:
array=`find . -name "$input"`
If you wanted to create an array, you would need to put parens around the output of find. So, naively, one could:
array=(`find . -name "$input"`) # don't do this
The problem is that the shell performs word splitting on the results of find
so that the elements of the array are not guaranteed to be what you want.
edited May 29 '18 at 17:23
answered Apr 29 '14 at 6:38
John1024John1024
82.8k9 gold badges76 silver badges106 bronze badges
82.8k9 gold badges76 silver badges106 bronze badges
Awesome! Thanks. But could you explain little more about last line? I mean redirection part. At first, I write "<<" and it show syntax error on "(". After several tries, I just copy your code to mine and it works. what is the meaning of '<' in last line?
– Juneyoung Oh
Apr 29 '14 at 8:14
^^ checkbash
manual for process redirection section.
– anishsane
Apr 29 '14 at 8:38
1
@JuneyoungOh Glad it helped. I added a section of process substitution.
– John1024
Apr 29 '14 at 17:52
2
@Rockallite That is a good observation but incomplete. While it is true that we don't split into multiple words, we still needIFS=
to avoid removal of whitespace from the beginnings or ends of the input lines. You can test this easily by comparing the output ofread var <<<' abc '; echo ">$var<"
with the output ofIFS= read var <<<' abc '; echo ">$var<"
. In the former case, the spaces before and afterabc
are removed. In the latter, they aren't. File names that begin or end with whitespace may be unusual but, it they exist, we want them processed correctly.
– John1024
Feb 24 '17 at 2:20
1
@jacderida Good point. I added a sentence to explainREPLY
.
– John1024
Aug 17 '17 at 20:33
|
show 11 more comments
Awesome! Thanks. But could you explain little more about last line? I mean redirection part. At first, I write "<<" and it show syntax error on "(". After several tries, I just copy your code to mine and it works. what is the meaning of '<' in last line?
– Juneyoung Oh
Apr 29 '14 at 8:14
^^ checkbash
manual for process redirection section.
– anishsane
Apr 29 '14 at 8:38
1
@JuneyoungOh Glad it helped. I added a section of process substitution.
– John1024
Apr 29 '14 at 17:52
2
@Rockallite That is a good observation but incomplete. While it is true that we don't split into multiple words, we still needIFS=
to avoid removal of whitespace from the beginnings or ends of the input lines. You can test this easily by comparing the output ofread var <<<' abc '; echo ">$var<"
with the output ofIFS= read var <<<' abc '; echo ">$var<"
. In the former case, the spaces before and afterabc
are removed. In the latter, they aren't. File names that begin or end with whitespace may be unusual but, it they exist, we want them processed correctly.
– John1024
Feb 24 '17 at 2:20
1
@jacderida Good point. I added a sentence to explainREPLY
.
– John1024
Aug 17 '17 at 20:33
Awesome! Thanks. But could you explain little more about last line? I mean redirection part. At first, I write "<<" and it show syntax error on "(". After several tries, I just copy your code to mine and it works. what is the meaning of '<' in last line?
– Juneyoung Oh
Apr 29 '14 at 8:14
Awesome! Thanks. But could you explain little more about last line? I mean redirection part. At first, I write "<<" and it show syntax error on "(". After several tries, I just copy your code to mine and it works. what is the meaning of '<' in last line?
– Juneyoung Oh
Apr 29 '14 at 8:14
^^ check
bash
manual for process redirection section.– anishsane
Apr 29 '14 at 8:38
^^ check
bash
manual for process redirection section.– anishsane
Apr 29 '14 at 8:38
1
1
@JuneyoungOh Glad it helped. I added a section of process substitution.
– John1024
Apr 29 '14 at 17:52
@JuneyoungOh Glad it helped. I added a section of process substitution.
– John1024
Apr 29 '14 at 17:52
2
2
@Rockallite That is a good observation but incomplete. While it is true that we don't split into multiple words, we still need
IFS=
to avoid removal of whitespace from the beginnings or ends of the input lines. You can test this easily by comparing the output of read var <<<' abc '; echo ">$var<"
with the output of IFS= read var <<<' abc '; echo ">$var<"
. In the former case, the spaces before and after abc
are removed. In the latter, they aren't. File names that begin or end with whitespace may be unusual but, it they exist, we want them processed correctly.– John1024
Feb 24 '17 at 2:20
@Rockallite That is a good observation but incomplete. While it is true that we don't split into multiple words, we still need
IFS=
to avoid removal of whitespace from the beginnings or ends of the input lines. You can test this easily by comparing the output of read var <<<' abc '; echo ">$var<"
with the output of IFS= read var <<<' abc '; echo ">$var<"
. In the former case, the spaces before and after abc
are removed. In the latter, they aren't. File names that begin or end with whitespace may be unusual but, it they exist, we want them processed correctly.– John1024
Feb 24 '17 at 2:20
1
1
@jacderida Good point. I added a sentence to explain
REPLY
.– John1024
Aug 17 '17 at 20:33
@jacderida Good point. I added a sentence to explain
REPLY
.– John1024
Aug 17 '17 at 20:33
|
show 11 more comments
If you are using bash
4 or later, you can replace your use of find
with
shopt -s globstar nullglob
array=( **/*"$input"* )
The **
pattern enabled by globstar
matches 0 or more directories, allowing the pattern to match to an arbitrary depth in the current directory. Without the nullglob
option, the pattern (after parameter expansion) is treated literally, so with no matches you would have an array with a single string rather than an empty array.
Add the dotglob
option to the first line as well if you want to traverse hidden directories (like .ssh
) and match hidden files (like .bashrc
) as well.
3
Maybenullglob
too…
– kojiro
Apr 29 '14 at 17:59
Yeah, I always forget that.
– chepner
Apr 29 '14 at 18:00
4
Note that this will not include the hidden files and directories, unlessdotglob
is set (this may or may not be wanted, but it's worth mentioning too).
– gniourf_gniourf
Apr 29 '14 at 18:03
Soooo many options :)
– chepner
Apr 29 '14 at 18:06
add a comment |
If you are using bash
4 or later, you can replace your use of find
with
shopt -s globstar nullglob
array=( **/*"$input"* )
The **
pattern enabled by globstar
matches 0 or more directories, allowing the pattern to match to an arbitrary depth in the current directory. Without the nullglob
option, the pattern (after parameter expansion) is treated literally, so with no matches you would have an array with a single string rather than an empty array.
Add the dotglob
option to the first line as well if you want to traverse hidden directories (like .ssh
) and match hidden files (like .bashrc
) as well.
3
Maybenullglob
too…
– kojiro
Apr 29 '14 at 17:59
Yeah, I always forget that.
– chepner
Apr 29 '14 at 18:00
4
Note that this will not include the hidden files and directories, unlessdotglob
is set (this may or may not be wanted, but it's worth mentioning too).
– gniourf_gniourf
Apr 29 '14 at 18:03
Soooo many options :)
– chepner
Apr 29 '14 at 18:06
add a comment |
If you are using bash
4 or later, you can replace your use of find
with
shopt -s globstar nullglob
array=( **/*"$input"* )
The **
pattern enabled by globstar
matches 0 or more directories, allowing the pattern to match to an arbitrary depth in the current directory. Without the nullglob
option, the pattern (after parameter expansion) is treated literally, so with no matches you would have an array with a single string rather than an empty array.
Add the dotglob
option to the first line as well if you want to traverse hidden directories (like .ssh
) and match hidden files (like .bashrc
) as well.
If you are using bash
4 or later, you can replace your use of find
with
shopt -s globstar nullglob
array=( **/*"$input"* )
The **
pattern enabled by globstar
matches 0 or more directories, allowing the pattern to match to an arbitrary depth in the current directory. Without the nullglob
option, the pattern (after parameter expansion) is treated literally, so with no matches you would have an array with a single string rather than an empty array.
Add the dotglob
option to the first line as well if you want to traverse hidden directories (like .ssh
) and match hidden files (like .bashrc
) as well.
edited Apr 29 '14 at 18:07
answered Apr 29 '14 at 17:58
chepnerchepner
283k40 gold badges280 silver badges379 bronze badges
283k40 gold badges280 silver badges379 bronze badges
3
Maybenullglob
too…
– kojiro
Apr 29 '14 at 17:59
Yeah, I always forget that.
– chepner
Apr 29 '14 at 18:00
4
Note that this will not include the hidden files and directories, unlessdotglob
is set (this may or may not be wanted, but it's worth mentioning too).
– gniourf_gniourf
Apr 29 '14 at 18:03
Soooo many options :)
– chepner
Apr 29 '14 at 18:06
add a comment |
3
Maybenullglob
too…
– kojiro
Apr 29 '14 at 17:59
Yeah, I always forget that.
– chepner
Apr 29 '14 at 18:00
4
Note that this will not include the hidden files and directories, unlessdotglob
is set (this may or may not be wanted, but it's worth mentioning too).
– gniourf_gniourf
Apr 29 '14 at 18:03
Soooo many options :)
– chepner
Apr 29 '14 at 18:06
3
3
Maybe
nullglob
too…– kojiro
Apr 29 '14 at 17:59
Maybe
nullglob
too…– kojiro
Apr 29 '14 at 17:59
Yeah, I always forget that.
– chepner
Apr 29 '14 at 18:00
Yeah, I always forget that.
– chepner
Apr 29 '14 at 18:00
4
4
Note that this will not include the hidden files and directories, unless
dotglob
is set (this may or may not be wanted, but it's worth mentioning too).– gniourf_gniourf
Apr 29 '14 at 18:03
Note that this will not include the hidden files and directories, unless
dotglob
is set (this may or may not be wanted, but it's worth mentioning too).– gniourf_gniourf
Apr 29 '14 at 18:03
Soooo many options :)
– chepner
Apr 29 '14 at 18:06
Soooo many options :)
– chepner
Apr 29 '14 at 18:06
add a comment |
Bash 4.4 introduced a -d
option to readarray
/mapfile
, so this can now be solved with
readarray -d '' array < <(find . -name "$input" -print0)
for a method that works with arbitrary filenames including blanks, newlines, and globbing characters.
From the manual (omitting other options):
mapfile [-d delim] [array]
-d
The first character ofdelim
is used to terminate each input line, rather than newline. Ifdelim
is the empty string,mapfile
will terminate a line when it reads a NUL character.
And readarray
is just a synonym of mapfile
.
add a comment |
Bash 4.4 introduced a -d
option to readarray
/mapfile
, so this can now be solved with
readarray -d '' array < <(find . -name "$input" -print0)
for a method that works with arbitrary filenames including blanks, newlines, and globbing characters.
From the manual (omitting other options):
mapfile [-d delim] [array]
-d
The first character ofdelim
is used to terminate each input line, rather than newline. Ifdelim
is the empty string,mapfile
will terminate a line when it reads a NUL character.
And readarray
is just a synonym of mapfile
.
add a comment |
Bash 4.4 introduced a -d
option to readarray
/mapfile
, so this can now be solved with
readarray -d '' array < <(find . -name "$input" -print0)
for a method that works with arbitrary filenames including blanks, newlines, and globbing characters.
From the manual (omitting other options):
mapfile [-d delim] [array]
-d
The first character ofdelim
is used to terminate each input line, rather than newline. Ifdelim
is the empty string,mapfile
will terminate a line when it reads a NUL character.
And readarray
is just a synonym of mapfile
.
Bash 4.4 introduced a -d
option to readarray
/mapfile
, so this can now be solved with
readarray -d '' array < <(find . -name "$input" -print0)
for a method that works with arbitrary filenames including blanks, newlines, and globbing characters.
From the manual (omitting other options):
mapfile [-d delim] [array]
-d
The first character ofdelim
is used to terminate each input line, rather than newline. Ifdelim
is the empty string,mapfile
will terminate a line when it reads a NUL character.
And readarray
is just a synonym of mapfile
.
edited Feb 8 at 19:38
answered Feb 6 at 19:53
Benjamin W.Benjamin W.
23.8k13 gold badges56 silver badges63 bronze badges
23.8k13 gold badges56 silver badges63 bronze badges
add a comment |
add a comment |
you can try something like
array=(`find . -type f | sort -r | head -2`)
, and in order to print the array values , you can try something like echo "$array[*]"
5
Breaks if there are filenames with spaces or glob characters.
– gniourf_gniourf
Dec 25 '17 at 9:13
add a comment |
you can try something like
array=(`find . -type f | sort -r | head -2`)
, and in order to print the array values , you can try something like echo "$array[*]"
5
Breaks if there are filenames with spaces or glob characters.
– gniourf_gniourf
Dec 25 '17 at 9:13
add a comment |
you can try something like
array=(`find . -type f | sort -r | head -2`)
, and in order to print the array values , you can try something like echo "$array[*]"
you can try something like
array=(`find . -type f | sort -r | head -2`)
, and in order to print the array values , you can try something like echo "$array[*]"
answered Aug 6 '15 at 6:02
Ahmed Al-HaffarAhmed Al-Haffar
881 silver badge5 bronze badges
881 silver badge5 bronze badges
5
Breaks if there are filenames with spaces or glob characters.
– gniourf_gniourf
Dec 25 '17 at 9:13
add a comment |
5
Breaks if there are filenames with spaces or glob characters.
– gniourf_gniourf
Dec 25 '17 at 9:13
5
5
Breaks if there are filenames with spaces or glob characters.
– gniourf_gniourf
Dec 25 '17 at 9:13
Breaks if there are filenames with spaces or glob characters.
– gniourf_gniourf
Dec 25 '17 at 9:13
add a comment |
In bash, $(<any_shell_cmd>)
helps to run a command and capture the output. Passing this to IFS
with n
as delimiter helps to convert that to an array.
IFS='n' read -r -a txt_files <<< $(find /path/to/dir -name "*.txt")
This will get only the first file of the results offind
into the array.
– Benjamin W.
Mar 12 at 21:17
add a comment |
In bash, $(<any_shell_cmd>)
helps to run a command and capture the output. Passing this to IFS
with n
as delimiter helps to convert that to an array.
IFS='n' read -r -a txt_files <<< $(find /path/to/dir -name "*.txt")
This will get only the first file of the results offind
into the array.
– Benjamin W.
Mar 12 at 21:17
add a comment |
In bash, $(<any_shell_cmd>)
helps to run a command and capture the output. Passing this to IFS
with n
as delimiter helps to convert that to an array.
IFS='n' read -r -a txt_files <<< $(find /path/to/dir -name "*.txt")
In bash, $(<any_shell_cmd>)
helps to run a command and capture the output. Passing this to IFS
with n
as delimiter helps to convert that to an array.
IFS='n' read -r -a txt_files <<< $(find /path/to/dir -name "*.txt")
edited Feb 8 at 19:37
Benjamin W.
23.8k13 gold badges56 silver badges63 bronze badges
23.8k13 gold badges56 silver badges63 bronze badges
answered Jan 26 '18 at 9:43
rashokrashok
6,58811 gold badges57 silver badges79 bronze badges
6,58811 gold badges57 silver badges79 bronze badges
This will get only the first file of the results offind
into the array.
– Benjamin W.
Mar 12 at 21:17
add a comment |
This will get only the first file of the results offind
into the array.
– Benjamin W.
Mar 12 at 21:17
This will get only the first file of the results of
find
into the array.– Benjamin W.
Mar 12 at 21:17
This will get only the first file of the results of
find
into the array.– Benjamin W.
Mar 12 at 21:17
add a comment |
You could do like this:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=(`find . -name '*'$input'*'`)
for i in "$array[@]"
do :
echo $i
done
2
There is a problem, if the file names have a space...
– anishsane
Apr 29 '14 at 7:11
Thanks. a lot. But as @anishsane pointed, empty spaces in filename should be considered in my program. Anyway Thanks!
– Juneyoung Oh
Apr 29 '14 at 8:15
add a comment |
You could do like this:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=(`find . -name '*'$input'*'`)
for i in "$array[@]"
do :
echo $i
done
2
There is a problem, if the file names have a space...
– anishsane
Apr 29 '14 at 7:11
Thanks. a lot. But as @anishsane pointed, empty spaces in filename should be considered in my program. Anyway Thanks!
– Juneyoung Oh
Apr 29 '14 at 8:15
add a comment |
You could do like this:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=(`find . -name '*'$input'*'`)
for i in "$array[@]"
do :
echo $i
done
You could do like this:
#!/bin/bash
echo "input : "
read input
echo "searching file with this pattern '$input' under present directory"
array=(`find . -name '*'$input'*'`)
for i in "$array[@]"
do :
echo $i
done
answered Apr 29 '14 at 7:07
user1357768user1357768
721 bronze badge
721 bronze badge
2
There is a problem, if the file names have a space...
– anishsane
Apr 29 '14 at 7:11
Thanks. a lot. But as @anishsane pointed, empty spaces in filename should be considered in my program. Anyway Thanks!
– Juneyoung Oh
Apr 29 '14 at 8:15
add a comment |
2
There is a problem, if the file names have a space...
– anishsane
Apr 29 '14 at 7:11
Thanks. a lot. But as @anishsane pointed, empty spaces in filename should be considered in my program. Anyway Thanks!
– Juneyoung Oh
Apr 29 '14 at 8:15
2
2
There is a problem, if the file names have a space...
– anishsane
Apr 29 '14 at 7:11
There is a problem, if the file names have a space...
– anishsane
Apr 29 '14 at 7:11
Thanks. a lot. But as @anishsane pointed, empty spaces in filename should be considered in my program. Anyway Thanks!
– Juneyoung Oh
Apr 29 '14 at 8:15
Thanks. a lot. But as @anishsane pointed, empty spaces in filename should be considered in my program. Anyway Thanks!
– Juneyoung Oh
Apr 29 '14 at 8:15
add a comment |
For me, this worked fine on cygwin:
declare -a names=$(echo "("; find <path> <other options> -printf '"%p" '; echo ")")
for nm in "$names[@]"
do
echo "$nm"
done
This works with spaces, but not with double quotes (") in the directory names (which aren't allowed in a Windows environment anyway).
Beware the space in the -printf option.
its not working for me on mac
– To Kra
Dec 28 '16 at 14:44
2
Broken and dangerous: will not handle quotes, and is subject to arbitrary code injection. DO NOT USE.
– gniourf_gniourf
Dec 25 '17 at 9:14
1
It looks like someone flagged this post for deletion. "It is wrong" is not a reason for deletion on SO. The user made an attempt to answer, it is on topic, and meets the criteria for answers. The downvote button is used to measure usefulness and correctness, not the deletion button.
– Joe Frambach
Mar 14 '18 at 21:27
1
As gniourf pointed out, it's not for environments where others enter the options on your system, e.g. web pages. But not everybody program for that environment. I used it for renaming files in directories.
– R Risack
Jan 29 at 10:53
add a comment |
For me, this worked fine on cygwin:
declare -a names=$(echo "("; find <path> <other options> -printf '"%p" '; echo ")")
for nm in "$names[@]"
do
echo "$nm"
done
This works with spaces, but not with double quotes (") in the directory names (which aren't allowed in a Windows environment anyway).
Beware the space in the -printf option.
its not working for me on mac
– To Kra
Dec 28 '16 at 14:44
2
Broken and dangerous: will not handle quotes, and is subject to arbitrary code injection. DO NOT USE.
– gniourf_gniourf
Dec 25 '17 at 9:14
1
It looks like someone flagged this post for deletion. "It is wrong" is not a reason for deletion on SO. The user made an attempt to answer, it is on topic, and meets the criteria for answers. The downvote button is used to measure usefulness and correctness, not the deletion button.
– Joe Frambach
Mar 14 '18 at 21:27
1
As gniourf pointed out, it's not for environments where others enter the options on your system, e.g. web pages. But not everybody program for that environment. I used it for renaming files in directories.
– R Risack
Jan 29 at 10:53
add a comment |
For me, this worked fine on cygwin:
declare -a names=$(echo "("; find <path> <other options> -printf '"%p" '; echo ")")
for nm in "$names[@]"
do
echo "$nm"
done
This works with spaces, but not with double quotes (") in the directory names (which aren't allowed in a Windows environment anyway).
Beware the space in the -printf option.
For me, this worked fine on cygwin:
declare -a names=$(echo "("; find <path> <other options> -printf '"%p" '; echo ")")
for nm in "$names[@]"
do
echo "$nm"
done
This works with spaces, but not with double quotes (") in the directory names (which aren't allowed in a Windows environment anyway).
Beware the space in the -printf option.
edited Jan 29 at 10:50
answered Nov 9 '16 at 11:50
R RisackR Risack
374 bronze badges
374 bronze badges
its not working for me on mac
– To Kra
Dec 28 '16 at 14:44
2
Broken and dangerous: will not handle quotes, and is subject to arbitrary code injection. DO NOT USE.
– gniourf_gniourf
Dec 25 '17 at 9:14
1
It looks like someone flagged this post for deletion. "It is wrong" is not a reason for deletion on SO. The user made an attempt to answer, it is on topic, and meets the criteria for answers. The downvote button is used to measure usefulness and correctness, not the deletion button.
– Joe Frambach
Mar 14 '18 at 21:27
1
As gniourf pointed out, it's not for environments where others enter the options on your system, e.g. web pages. But not everybody program for that environment. I used it for renaming files in directories.
– R Risack
Jan 29 at 10:53
add a comment |
its not working for me on mac
– To Kra
Dec 28 '16 at 14:44
2
Broken and dangerous: will not handle quotes, and is subject to arbitrary code injection. DO NOT USE.
– gniourf_gniourf
Dec 25 '17 at 9:14
1
It looks like someone flagged this post for deletion. "It is wrong" is not a reason for deletion on SO. The user made an attempt to answer, it is on topic, and meets the criteria for answers. The downvote button is used to measure usefulness and correctness, not the deletion button.
– Joe Frambach
Mar 14 '18 at 21:27
1
As gniourf pointed out, it's not for environments where others enter the options on your system, e.g. web pages. But not everybody program for that environment. I used it for renaming files in directories.
– R Risack
Jan 29 at 10:53
its not working for me on mac
– To Kra
Dec 28 '16 at 14:44
its not working for me on mac
– To Kra
Dec 28 '16 at 14:44
2
2
Broken and dangerous: will not handle quotes, and is subject to arbitrary code injection. DO NOT USE.
– gniourf_gniourf
Dec 25 '17 at 9:14
Broken and dangerous: will not handle quotes, and is subject to arbitrary code injection. DO NOT USE.
– gniourf_gniourf
Dec 25 '17 at 9:14
1
1
It looks like someone flagged this post for deletion. "It is wrong" is not a reason for deletion on SO. The user made an attempt to answer, it is on topic, and meets the criteria for answers. The downvote button is used to measure usefulness and correctness, not the deletion button.
– Joe Frambach
Mar 14 '18 at 21:27
It looks like someone flagged this post for deletion. "It is wrong" is not a reason for deletion on SO. The user made an attempt to answer, it is on topic, and meets the criteria for answers. The downvote button is used to measure usefulness and correctness, not the deletion button.
– Joe Frambach
Mar 14 '18 at 21:27
1
1
As gniourf pointed out, it's not for environments where others enter the options on your system, e.g. web pages. But not everybody program for that environment. I used it for renaming files in directories.
– R Risack
Jan 29 at 10:53
As gniourf pointed out, it's not for environments where others enter the options on your system, e.g. web pages. But not everybody program for that environment. I used it for renaming files in directories.
– R Risack
Jan 29 at 10:53
add a comment |
protected by gniourf_gniourf Dec 25 '17 at 8:56
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?