Converting a working command into shell script file which gets arguments Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Converting a working command into shell script file which gets arguments without wasting too much if your time.

The question is published on by Tutorial Guruji team.

Hi my working command is:

grep -l "my text" file*.ext|xargs ls -lart

this command is very useful for me and I wanted to create a shell file which does it with fewer typing, like this:

fn "my text" file*.ext

I came to this shell script file:

grep -l "$1" "$2"|xargs ls -lart

which is not working, even the first part is not working:

grep -l "$1" "$2"

which returns null

Answer

Your script will need to take more than two arguments.

Before the shell executes grep in the command

grep -l "my text" file*.ext

the filename globbing pattern file*.ext is expanded to all matching filenames. The command line that is finally run will therefore be

grep -l "my text" file1.ext file2.ext file3.ext

(if those are the files that matches the pattern)

Therefore, your script may look like

#!/bin/sh

pattern=$1
shift

grep -l -e "$pattern" "$@" | xargs ls -lrt

Here, the pattern is saved into a variable, and then shifted off the list of command line arguments. The remaining arguments is a list of filenames (if the filename globbing pattern on the command line matches) and is available in "$@".

Make sure you double quote $@. This will make $@ expand to the list of individually quoted command line arguments.

I’ve removed the -a option from ls as it’s not needed when giving explicit filenames to list. I’m also using grep with -e to specify the pattern, as a pattern with an initial dash (-) may otherwise confuse grep.


If it wasn’t for the sorting, I would have suggested the following find command instead of your pipeline (correctly handles filenames with spaces and newlines):

find . -type f -name "$filepattern" -exec grep -q -e "$pattern" {} ';' -ls

This looks for files with names matching what’s in $filepattern, and with contents matching what’s in $pattern, and then produces ls -l-like output. The search is performed recursively in the current directory.

As part of a script:

#!/bin/sh

pattern=$1
filepattern=$2

find . -type f -name "$filepattern" -exec grep -q -e "$pattern" {} ';' -ls

This script would need to be called in such a way that the filename globbing pattern isn’t expanded by the shell when calling it:

$ ./script.sh 'my text' 'file*.ext'
We are here to answer your question about Converting a working command into shell script file which gets arguments - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji