Linux bash - Find file with pattern containing spaces [duplicate] - linux

This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed 21 days ago.
I'm using a shell script on Linux that is processing some files from a directory based on a pattern.
The pattern can contain spaces.
The question is how do I get the list of files that match the pattern?
Example:
This is the list of files:
file_without_spaces.vol-1.txt
file_without_spaces.vol-2.txt
file with spaces.vol-1.txt
file with spaces.vol-2.txt
file with spaces.vol-3.txt
Result when the pattern is "file_without_spaces":
file_without_spaces.vol-1.txt
file_without_spaces.vol-2.txt
Result when the pattern is "file with spaces":
file with spaces.vol-1.txt
file with spaces.vol-2.txt
file with spaces.vol-3.txt
The pattern comes in an env variable, let's call it PATTERN.
Grepping for the pattern does not work, as it may contain spaces which grep cannot handle. Same for using the pattern as a parameter to find, e.g. find <dir> -name $PATTERN

Grep and find can handle spaces just fine. You simply need to quote them:
find <dir> -name "$PATTERN"

Related

How to extract the file name and change the ending in bash? [duplicate]

This question already has answers here:
Extract filename and extension in Bash
(38 answers)
How do I rename the extension for a bunch of files?
(28 answers)
Closed 3 years ago.
I have a bash script that accepts file names that end with .in, for example a1.in a2.in, and I want to take that argument and extract the a1 and add .out to it, how do I do that?
I know accepting an argument is $1 - but how do I extract the a1?
To remove a fixed suffix from an argument (or other variable) use ${1%.in} -- that will remove the trailing .in or do nothing if the argument does not end in .in. To add a suffix, just add it: ${1%.in}.out
To remove any suffix, you can use glob patterns after the % like so: ${1%.*}. This will remove the shortest matching suffix. You can remove the longest matching suffix with %%: ${1%%.*}
If your files have only one extension:
$ echo "a.in" | cut -d '.' -f1
a

Bash script doesn't evaluate variable in filename [duplicate]

This question already has answers here:
What is the difference between ${var}, "$var", and "${var}" in the Bash shell?
(7 answers)
Closed 5 years ago.
I have a bash script which creates a backup of my folder. It should name the tar gz file using a version number but it doesn't:
#!/bin/bash
ver='1.2.3'
tar czf $ver_myfolder.tar.gz .
Expected output:
1.2.3_myfolder.tar.gz
Actual output:
_myfolder.tar.gz
If I append the variable like this:
#!/bin/bash
ver='1.2.3'
tar czf myfolder-$ver.tar.gz .
It works
You should use ${var} here since you are appending underscore after it which is considered a valid character for variable names. Due to that fact shell doesn't know whether you're expanding variable name $ver or $ver_myfolder:
ver='1.2.3'
tar czf "${ver}_myfolder.tar.gz" .
Since $ver_myfolder is unset, you get an empty value.
Because the underscore is a valid character for a variable name, you should use braces to explicitly specify the range of your variable:
${ver}_myfolder.tar.gz
^ ^
Without braces, Bash will actually try to parse
${ver_myfolder}.tar.gz
For your edited question, it is because the dot is not a valid character for a variable name, so Bash will not attempt to parse the dot into the name lookup. Even if you put it into braces, a variable name containing a dot is still invalid:
$ echo ${ver.}
bash: ${ver.}: bad substitution
$ ver.=1.2.3
ver.=1.2.3: command not found

shell script to list file names alone in a directory & rename it [duplicate]

This question already has answers here:
How can I remove the extension of a filename in a shell script?
(15 answers)
Closed 6 years ago.
I'm new to scripting concept.. I have a requirement to rename multiple files in a directory like filename.sh.x into filename.sh
First I tried to get the file names in a particular directory.. so i followed the below scripting code
for entry in PathToThedirectory/*sh.x
do
echo $entry
done
& the above code listed down all the file names with full path..
But my expected o/p is : to get file names alone like abc.sh.x,
so that I can proceed with the split string mechanism to perform rename
operation easily...
help me to solve this ... Thanks in advance
First approach trying to follow OP suggestions:
for i in my/path/*.py.x
do
basename=$(basename "$i")
mv my/path/"$basename" my/path/"${basename%.*}"
done
And maybe, you can simplify it:
for i in my/path/*.py.x
do
mv "$i" "${i%.*}";
done
Documentation regarding this kind of operation (parameter expansion): https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
In particular:
${parameter%word} : The word is expanded to produce a pattern just as in filename expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the value of parameter with the shortest matching pattern (the ‘%’ case) or the longest matching pattern (the ‘%%’ case) deleted
So, ${i%.*} means:
Take $i
Match .* at the end of its value (. being a literal character)
Remove the shortest matching pattern
Look into prename (installed together with the perl package on ubuntu).
Then you can just do something like:
prename 's/\.x$//' *.sh.x
In ksh you can do this:
for $file in $(ls $path)
do
new_file=$(basename $path/$file .x)
mv ${path}/${file} ${path}/${new_file}
done
This should do the trick:
for file in *.sh.x;
do
mv "$file " "${file /.sh.x}";
done
Running this rename command from the root directory should work:
rename 's/\.sh\.x$/.sh/' *.sh.x
for i in ls -la /path|grep -v ^d|awk '{print $NF}'
do
echo "basename $i"
done
it will give u the base name of all files or you can try below
find /path -type f -exec basename {} \;

Change the output of find command [duplicate]

This question already has answers here:
How to strip leading "./" in unix "find"?
(8 answers)
Closed 8 years ago.
Hello guys I'm using the find command to find the .apk files in a directory. But the output of the find command is **./**foo.apk.
I don't want to have this ./.
cd output/dist
output_apk=`find ./ -name "*.apk" -print0`
echo "$output_apk"
The output is ./foo.apk.
I have try the sed command with no luck.
find output/dist -name "*.apk" |
sed 's%^output/dist/%%'
This also avoids the useless cd and removes the erroneous -print0. If you are not piping into a program which requires null-terminated input, this option is wrong.

Best way to find the numeric value in UNIX file system [duplicate]

This question already has answers here:
How to find all files containing specific text (string) on Linux?
(54 answers)
Closed 8 years ago.
I need to grep for a particular port number from a huge set of files.
I am using a command:
find . |xargs grep "9461"
But it does not finds all the occurrences for number 9461.
Can anyone suggest a better unix/linux command to do so.
The kind of files it gets is : x.log, y.txt,z.htm, a.out etc files
But it was not able to get abc.conf files
You surely have some reason for using find in combination with grep, but just in case:
You can replace your command by:
grep -r "9461" .
and if you want even line numbers
grep -rn "9461" .
As JonathanLefflero commented, there is also the option -e that make grep match againt a regular expression, so, the ultimate command would be
grep -rne 9461
You should take a look on grep man page
A final note, you should check if what you want to grep is "9461" or 9461 without "".

Resources