[SOLVED] string search in .odt document directories
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's 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.
This is waaaaaaay beyond my range, but thanks a ton! I'll come back when I am big and strong....
Let's see. I'll try to provide an explanation of what's happening, but since I'm not an expert there'll be things I get wrong and some things I can't explain at all. I hope someone will help out then!
The code, once again:
Code:
#!/bin/bash
# script name: odf-grep.sh
# usage: from the appropriate folder, run "odf-grep.sh search_string"
[ "$1" ] || { echo "You forgot the search string!" & exit; }
find . -type f -name "*.od*" | while read -r i ; do
unzip -c "$i" | grep -iq "$1" && echo "string found in $i"
done
As an example, I have a bunch of .ods and .odt files in ~/Dropbox/CurrSoc/MCM/old and I want to know which .ods/.odt files have the phrase "sinking fund". So, in the terminal, I navigate to the relevant folder and run odf-grep.sh "sinking fund". This is the output:
Code:
string found in ./IE201605May.ods
string found in ./2018-May-mcm-agenda.odt
string found in ./20150329-mcm-agenda-draft.odt
(Note that I have odf-grep.sh located in ~/bin which is recognized by the system as a location for executables. Check your set-up by running echo $PATH.)
What it does:
[ "$1" ] || { echo "You forgot the search string!" & exit; }
At the outset, the script checks whether you have provided the search string or not. If you haven't provided a search term, the script exits.
[ "$1" ] is shorthand for testing whether the search term is provided or not. See https://www.lifewire.com/test-linux-...ommand-4097166 for a simple explanation about tests in Bash and the use of "||" and "&&" both of which are used in this script.
In this instance, "$1" refers to the search string. (I think the technical term is "positional parameter".)
If it's not present the test fails, a message is echoed to the screen and the script exits.
If a search string is provided, the rest of the script kicks in.
find . -type f -name "*.od*"
"." indicates that find should start in the current folder and work down (recurse) into subfolders
"-type f" specifies that files are to be searched
"-name" precedes the filenames to be searched; in this case, we're looking at any open document format files.
You can run find . -type f -name "*.od*" separately just to see what the output of find looks like.
| while read -r i ; do
"|" takes the output of the command on the left and passes or pipes it to another operation, in this case a while loop
In imprecise terms, for each file found by find and represented by "i", we're asking for something to be done
unzip -c "$i"
This is simple: the target file is unzipped (but the contents aren't stored on your system unlike using unzip without -c )
| grep -iq "$1"
the contents of the unzip operations are piped to the grep command which searches the contents for the presence of the specified string, the "$1". The search is case-insensitive (because of "-i") and only communicates whether the term was found or not because of "-q" via grep's exit status
&& echo "string found in $i"
If the preceding grep operation was successful (= the *.od* file contains the search string) because of && (see the lifewire link for && and ||), output a message with the file's relative path and name.
This is invaluable - it is a veritable education! I can't begin to tell you how grateful I am for the trouble you have taken. It will take me a little time to work my way through this - and I might still have some questions after I have - but I can recall formal courses, where I've been taught less - and certainly less meticulously.
Let's say you want to look through files LibreOffice Writer (.odt) or LibreOffice Calc (.ods) files located in ~/Documents for the phrase "sinking fund". In your terminal move to ~/Documents by running
cd ~/Documents
Your terminal prompt should change to reflect the new "current working directory".
Then run
$PATH
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
...
Does this have a bearing on where my odf-grep.sh script goes?
Mint maybe doing things differently than Ubuntu.
1: Could you post the output of cat ~/.bash_profile here?
2: You can have your scripts anywhere you like but if they're not in PATH, you'll need to reference the entire path each time you want to run them (or make an alias that includes the path).
3: And, of course, the script should be made executable, either via your File Manager > Properties > Permissions or by running chmod +x odf-grep.sh in your terminal where your script is located.
$ cat ~/.profile
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
Great. So look at what I've quoted from your .profile. It just means that if you create ~/bin and/or ~/.local/bin, both those folders will be added to your $PATH and that executable scripts placed there can be used like any other system command (without you having to provide the path).
A log out and login maybe needed after you create ~/bin and/or ~/.local/bin. I have just ~/bin.
(You may get away by just "sourcing" ~/.profile after you've created the folder instead of rebooting. I don't know for sure.)
-----
BTW, this forum prefers that content copied from your terminal and pasted here be enclosed in "code" tags. Highlight the pasted stuff and then click the "#" icon above the posting area.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.