The selection should be based on submitting an argument when the script is executed.


#This script echoes a text and creates a file

echo "welcome. Will create a file with content in this folder"

ls -l | grep .txt > files_in_folder
  • 2
    Welcome to the site. As a general note, please be aware that parsing the output of ls is highly disrecommended, as special characters in the filenames can lead to strange results. Btw. if you are new to shell scripting, have a look at GreyCat and Lhunath's Bash Guide and take a look at shellcheck (also available as standalone tool) which is really helpful in preventing syntax (and some logic) errors. – AdminBee Apr 24 at 12:22
  • 1
    Note that i) your script does not list all files ending with .txt in the folder where your script is. Instead, it lists all files or directories whose name contains txt preceded by any other character. It will also find notAtxtFile for example. Also, it doesn't search the folder where your script is but the folder where you are when you run your script. ii) all you need is ls *txt, no grep. – terdon Apr 24 at 12:34
  • "The selection should be based on submitting an argument when the script is executed". My bad, I wasn't clear enough – Albin Westlin Apr 24 at 12:41
  • OK, but please edit your question and clarify. Do you want something like script.sh txt which will then return all files or directories in the current folder whose name contains txt? Or do you maybe want to launch the script and then ask the user for input (I hope not, that's horribly annoying for the users)? We need to understand exactly what you need in order to be able to help you. – terdon Apr 24 at 14:31
  • When I run the script ./script, a file with all the files that ends with .txt in my home directory gets printed to the word file. Now I'm supposed to add and argument instead of a command line. So basically add an argument to replace for a command line. Turn "ls -l" into an argument | grep .txt > files_in_folder. Can you even do that? – Albin Westlin Apr 25 at 20:37

Assuming that the user of the script uses an argument that is the filename suffix that they want to select filenames with, for example .txt.


printf '%s\n' ./*"$1"

This would list all names in the current directory that ends with the given filename suffix. The printf command would take the list generate when the shell expands the pattern (which includes the argument given by the user at the end) and then output each list entry (filename in this case) on their own line according to the printf format string. The format string used here is %s\n, which means "some string followed by a newline character".

Would you want to use ls -l to get a "long listing" that includes file meta-data:


ls -ld ./*"$1"

The -d is needed as to not list the contents of directories matching the pattern. Again, the shell expands the given pattern and invokes ls -ld with the list of matching filenames.

To include names in subdirectories, using bash:


shopt -s globstar
printf '%s\n' ./**/*"$1"

The ** pattern matches recursively into subdirectories if it's enabled with the globstar option. You could also use ls -ld with the above pattern, obviously, but it has the potential to break if the expansion of the pattern results in many thousands of filenames.

To restrict the list to only regular files (i.e. not directory names etc., but including hidden names), while going into subdirectories:


find . -name "*$1" -type f

Add -ls to the end if you require something that looks like the ls -ld output.

This would also work even if there are many thousands of matching filenames, but now the argument can no longer contain filename globbing characters (i.e. the command above would not find files whose names end with something like the literal string .* if you give '.*' as the argument to the script).

In all cases, the $1 should be quoted. In the find command, the * needs to be quoted too as find does its own matching of pattern given to -name. In the other cases, * should be unquoted to allow the shell to expand it.

Redirect the output to a file, either inside the script or when you run it, if that is part of the requirement.

Each one of the above variations of the script would be invoked in the same way:

./myscript.sh .txt
| improve this answer | |

You use it like below : ( Note all the double quotes in the arguments passed to the script )

$first_cmd | $second_cmd > outputfile.txt

Execute :

$ ./temp.sh "ls -lrt" "grep '\.txt$'"

Check output :

$ cat outputfile.txt 
***all the filename with .txt will print
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.