I want to pass a variable in my grep command in Linux bash script. Variable is a text file from Internet and i want to find some words in it.
I have tried the following command in my bash:
cat "$var" | grep -Po '(?<=\d[a-zA-Z]).*\..*(?=[a-zA-Z]\d)'
echo "$var" | grep -Po '(?<=\d[a-zA-Z]).*\..*(?=[a-zA-Z]\d)'
grep -Po '(?<=\d[a-zA-Z]).*\..*(?=[a-zA-Z]\d)' <<< "$var"
but i dont get a right Result.
How can i do it?
Here is my bash:
#!/bin/sh
urltext=$(curl -s https://example.com)
string=$(grep -Po '(?<=\d[a-zA-Z]).*\..*(?=[a-zA-Z]\d)' "$urltext" | tr '.' '\n' )
cat $string
What's supposed to be contained in the variable ?
It's a file ?
grep <options> <expression> "$var"
It's a string ?
echo "$var"|grep <options> <expression>
grep <options> <expression> <(echo "$var")
NB : try -e option if there are several lines in $var
Related
I have to print number of folders in my directory, so i use
ls -l $1| grep "^d" | wc -l
after that, I would liked to add a text in the same line.
any ideas?
If you don’t want to use a variable to hold the output you can use echo and put your command in $( ) on that echo line.
echo $(ls -l $1| grep "^d" | wc -l ) more text to follow here
Assign the result to a variable, then print the variable on the same line as the directory name.
folders=$(ls -l "$1" | grep "^d" | wc -l)
printf "%s %d\n" "$1" "$folders"
Also, remember to quote your variables, otherwise your script won't work when filenames contain whitespace.
I want to make a bash script to use grep to search for lines which have multiple patterns (case-insensitive). I want to create a bash script which I can use as follows:
myscript file.txt pattern1 pattern2 pattern3
and it should get traslated to:
grep -i --color=always pattern1 file.txt | grep -i pattern2 | grep -i pattern3
I tried following bash script, but it is not working:
#!/bin/bash
grep -i --color=always $2 $1 | grep -i $3 | grep -i $4 | grep -i $5 | grep -i $6 | grep -i $7
The error is:
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
I think you can do a recursive function:
search() {
if [ $# -gt 0 ]; then
local pat=$1
shift
grep "$pat" | search "$#"
else
cat
fi
}
In your script you would call this function and pass the search patterns as arguments. Say that $1 is the file and the rest of the arguments are patterns then you would do
file=$1
shift
cat "$file" | search "$#"
When you have GNU awk, you can use
awk 'BEGIN {IGNORECASE=1} /pattern1/ && /pattern2/ && /pattern3/' file.txt
EDIT:
You can use this in a script like this:
inputfile="$1"
shift
awk -f <(echo "BEGIN {IGNORECASE=1}"; printf " /%s/ &&" $* | sed 's/&&$//') "${inputfile}"
If you omit one argument or other at the end, so that $3 etc. will be missing, then some grep command will not receive an argument and will whine.
I'm a shell script newbie, so I must be doing something stupid, why won't this work:
#!/bin/sh
myFile=$1
while read line
do
ssh $USER#$line <<ENDSSH
ls -d foo* | wc -l
count=`ls -d foo* | wc -l`
echo $count
ENDSSH
done <$myfile
Two lines should be printed, and each should have the same value... but they don't. The first print statement [the result of ls -d foo* | wc -l] has the correct value, the second print statement is incorrect, it always prints blank. Do I need to do something special to assign the value to $count?
What am I doing wrong?
Thanks
#!/bin/sh
while read line; do
echo Begin $line
ssh $USER#$line << \ENDSSH
ls -d foo* | wc -l
count=`ls -d foo* | wc -l`
echo $count
ENDSSH
done < $1
The only problem with your script was that when the heredoc token is not quoted, the shell does variable expansion, so $count was being expanded by your local shell before the remote commands were shipped off...
I've got two test files, namely, ttt.txt and ttt2.txt, the Content of which is shown as below:
#ttt.txt
(132) 123-2131
543-732-3123
238-3102-312
#ttt2.txt
1
2
3
I've already tried the following commands in bash and it works fine:
if grep -oE "(\(\d{3}\)[ ]?\d{3}-\d{4})|(\d{3}-\d{3}-\d{4})" ttt1.txt ; then echo "found"; fi
# with output 'found'
if grep -oE "(\(\d{3}\)[ ]?\d{3}-\d{4})|(\d{3}-\d{3}-\d{4})" ttt2.txt ; then echo "found"; fi
But when I combine the above command with xargs, it complains error '-bash: syntax error near unexpected token `then''. Could anyone give me some explanation? Thanks in advance!
ll | awk '{print $9}' | grep ttt | xargs -I $ if grep --quiet -oE "(\(\d{3}\)[ ]?\d{3}-\d{4})|(\d{3}-\d{3}-\d{4})" $; then echo "found"; fi
$ is a special character in bash (it marks variables) so don't use it as your xargs marker, you'll only get confused.
The real problem here though is that you are passing if grep --quiet -oE "(\(\d{3}\)[ ]?\d{3}-\d{4})|(\d{3}-\d{3}-\d{4})" $ as the argument to xargs, and then the remainder of the line is being treated as a new command, because it breaks at the ;.
You can wrap the whole thing in a sub-invocation of bash, so that xargs sees the whole command:
$ ll | awk '{print $9}' | grep ttt | xargs -I xx bash -c 'if grep --quiet -oE "(\(\d{3}\)[ ]?\d{3}-\d{4})|(\d{3}-\d{3}-\d{4})" xx; then echo "found"; fi'
found
Finally, ll | awk '{print $9}' | grep ttt is a needlessly complicated way of listing the files that you're looking for. You actually you don't need any of the code above, just do this:
$ if grep --quiet -oE "(\(\d{3}\)[ ]?\d{3}-\d{4})|(\d{3}-\d{3}-\d{4})" ttt*; then echo "found"; fi
found
Alternatively, if you want to process each file in turn (which you don't need here, but you might want when this gets more complicated):
for file in ttt*
do
if grep --quiet -oE "(\(\d{3}\)[ ]?\d{3}-\d{4})|(\d{3}-\d{3}-\d{4})" "$file"
then
echo "found"
fi
done
I am looking for a linux command that searches a string in a text file,
and highlights (colors) it on every occurence in the file, WITHOUT omitting text lines (like grep does).
I wrote this handy little script. It could probably be expanded to handle args better
#!/bin/bash
if [ "$1" == "" ]; then
echo "Usage: hl PATTERN [FILE]..."
elif [ "$2" == "" ]; then
grep -E --color "$1|$" /dev/stdin
else
grep -E --color "$1|$" $2
fi
it's useful for stuff like highlighting users running processes:
ps -ef | hl "alice|bob"
Try
tail -f yourfile.log | egrep --color 'DEBUG|'
where DEBUG is the text you want to highlight.
command | grep -iz -e "keyword1" -e "keyword2" (ignore -e switch if just searching for a single word, -i for ignore case, -z for treating as a single file)
Alternatively,while reading files
grep -iz -e "keyword1" -e "keyword2" 'filename'
OR
command | grep -A 99999 -B 99999 -i -e "keyword1" "keyword2" (ignore -e switch if just searching for a single word, -i for ignore case,-A and -B for no of lines before/after the keyword to be displayed)
Alternatively,while reading files
grep -A 99999 -B 99999 -i -e "keyword1" "keyword2" 'filename'
command ack with --passthru switch:
ack --passthru pattern path/to/file
I take it you meant "without omitting text lines" (instead of emitting)...
I know of no such command, but you can use a script such as this (this one is a simple solution that takes the filename (without spaces) as the first argument and the search string (also without spaces) as the second):
#!/usr/bin/env bash
ifs_store=$IFS;
IFS=$'\n';
for line in $(cat $1);
do if [ $(echo $line | grep -c $2) -eq 0 ]; then
echo $line;
else
echo $line | grep --color=always $2;
fi
done
IFS=$ifs_store
save as, for instance colorcat.sh, set permissions appropriately (to be able to execute it) and call it as
colorcat.sh filename searchstring
I had a requirement like this recently and hacked up a small program to do exactly this. Link
Usage: ./highlight test.txt '^foo' 'bar$'
Note that this is very rough, but could be made into a general tool with some polishing.
Using dwdiff, output differences with colors and line numbers.
echo "Hello world # $(date)" > file1.txt
echo "Hello world # $(date)" > file2.txt
dwdiff -c -C 0 -L file1.txt file2.txt