| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Tue Nov 18, 2008 8:26 am Post subject: Need help with a bash script |
|
|
Hello everyone,
Yes, this may not be the best group to post this message, but I found
some junk, crap and smut in some groups related to linux programming
and I got worried that my post would not be seen and be replied in
those places.
Here is part of a short script that will copy fýles containing certain
patterns (in this case "pat1" and "pat2") in different directories to
a single directory whose path is stored in the variable named
"FILEDIR"
for FILE in $(find * |grep 'pat1' | grep 'pat2'); do
cp $FILE $FILEDIR
done
I would like to pass the patterns (1 or more) and the FILEDIR as
command line arguments to the script. However, I could not figure out
how to pass a variðable number of patterns as arguments. If anyone can
suggest a way, I would be grateful. (Teaching me how to combine
patterns in one single grep call will also work)
Best wishes for everyone,
Hurol Aslan |
|
| |
|
Back to top |
Stephane Chazelas Guest
|
Posted: Tue Nov 18, 2008 1:11 pm Post subject: Re: Need help with a bash script |
|
|
2008-11-18, 07:36(-05), Maxwell Lol:
[...]
| Quote: | Here is part of a short script that will copy f??les containing certain
patterns (in this case "pat1" and "pat2") in different directories to
a single directory whose path is stored in the variable named
"FILEDIR"
for FILE in $(find * |grep 'pat1' | grep 'pat2'); do
cp $FILE $FILEDIR
done
[...]
Multiple patterns in grep can be done using egrep or grep -E
i.e.
egrep 'pat1|pat2'
|
Or with grep without "-E" with
grep -e pat1 -e pat2
or grep 'pat1
pat2'
But the OPs wanted file paths that match *both* pat1 and pat2,
not those that match either pat1 and pat2.
[...]
| Quote: | Here's my attempt
#!/bin/sh
FILEDIR=${1?'Missing required destination directory'}
shift
PAT="$@"
PAT=$(echo "$@" | tr ' ' '|')
IFS=
find . -type f | egrep "$PAT" | while read line
do
echo cp "$line" "$FILEDIR"
done
|
FILEDIR=${1?}
shift
for i do
filter=" | grep -e \"\${$#}\"$filter"
shift
done
eval "find . -type f $filter" |
sed 's/./\\&/g' | xargs -I@ cp -- @ "$FILEDIR"
But beware that you may end up overwriting files and that
solution doesn't work if some filenames contain newline
characters.
You can optimise it a lot if you're OK to switch from BRE to
EREs with:
FILEDIR=${1?}
export FILEDIR
shift
find . -type f | awk '
BEGIN {
for (n = 1; n < ARGC; n++)
a[n] = ARGV[n]
ARGC = 1
}
{
for (i = 1; i < n; i++)
if ($0 !~ a[i]) next
gsub(/./, "\\\\&")
print
}' "$@" | xargs sh -c '
[ "$#" -gt 0 ] || exit
exec cp -- "$@" "$FILEDIR"' inline
(POSIX environment assumed)
--
Stéphane |
|
| |
|
Back to top |
Guest
|
Posted: Tue Nov 18, 2008 1:29 pm Post subject: Re: Need help with a bash script |
|
|
Thanks for so many responses in such a short time.
As an additional explanation, the filenames did have to contain both
patterns, so an OR would not work for me. The script was for
collecting homeworks delivered via ftp (yes, probably there are better
ways for delivery; still improving) and I wanted to use parameters
rather than rewriting the script for every course or every homework.
I appreciate all the responses,
Hurol Aslan |
|
| |
|
Back to top |
Joerg Guest
|
Posted: Tue Nov 18, 2008 3:04 pm Post subject: Re: Need help with a bash script |
|
|
sirlousy@gmail.com wrote:
| Quote: | Hello everyone,
Yes, this may not be the best group to post this message, but I
found some junk, crap and smut in some groups related to linux
programming and I got worried that my post would not be seen and
be replied in those places.
Here is part of a short script that will copy fýles containing
certain patterns (in this case "pat1" and "pat2") in different
directories to a single directory whose path is stored in the
variable named "FILEDIR"
for FILE in $(find * |grep 'pat1' | grep 'pat2'); do
cp $FILE $FILEDIR
done
I would like to pass the patterns (1 or more) and the FILEDIR as
command line arguments to the script. However, I could not
figure out how to pass a variðable number of patterns as
arguments. If anyone can suggest a way, I would be grateful.
(Teaching me how to combine patterns in one single grep call
will also work)
Best wishes for everyone,
Hurol Aslan
|
You could use shift for reading a variable number of arguments
Joerg
--
For email use g m x d o t n e t |
|
| |
|
Back to top |
Gregory Shearman Guest
|
Posted: Tue Nov 18, 2008 3:16 pm Post subject: Re: Need help with a bash script |
|
|
On 2008-11-18, sirlousy@gmail.com <sirlousy@gmail.com> wrote:
| Quote: | Hello everyone,
Yes, this may not be the best group to post this message, but I found
some junk, crap and smut in some groups related to linux programming
and I got worried that my post would not be seen and be replied in
those places.
Here is part of a short script that will copy fıles containing certain
patterns (in this case "pat1" and "pat2") in different directories to
a single directory whose path is stored in the variable named
"FILEDIR"
for FILE in $(find * |grep 'pat1' | grep 'pat2'); do
cp $FILE $FILEDIR
done
|
It's rather clumsy. Do you really need the grep patterns? Can you get by
with the shell's file globbing? It would mean:
for FILE in *.pat1 *.pat2;do
cp $FILE $FILEDIR
done
| Quote: | I would like to pass the patterns (1 or more) and the FILEDIR as
command line arguments to the script. However, I could not figure out
how to pass a variÄŸable number of patterns as arguments. If anyone can
suggest a way, I would be grateful. (Teaching me how to combine
patterns in one single grep call will also work)
|
regular expressions can be OR'd by using the bar '|' eg
grep -e 'pat1|pat2' yourfile.txt
(you might need to add an 'escape' or backslash to stop the shell from
gobbling the '|'.
--
Regards,
Gregory.
Gentoo Linux - Penguin Power |
|
| |
|
Back to top |
pk Guest
|
Posted: Tue Nov 18, 2008 3:28 pm Post subject: Re: Need help with a bash script |
|
|
On Tuesday 18 November 2008 09:26, sirlousy@gmail.com wrote:
| Quote: | Here is part of a short script that will copy fıles containing certain
patterns (in this case "pat1" and "pat2") in different directories to
a single directory whose path is stored in the variable named
"FILEDIR"
for FILE in $(find * |grep 'pat1' | grep 'pat2'); do
cp $FILE $FILEDIR
done
I would like to pass the patterns (1 or more) and the FILEDIR as
command line arguments to the script. However, I could not figure out
how to pass a variÄŸable number of patterns as arguments. If anyone can
suggest a way, I would be grateful. (Teaching me how to combine
patterns in one single grep call will also work)
|
From what I see above, you want to select files whose names match both pat1
AND pat2. Is that correct? |
|
| |
|
Back to top |
Maxwell Lol Guest
|
Posted: Tue Nov 18, 2008 6:36 pm Post subject: Re: Need help with a bash script |
|
|
sirlousy@gmail.com writes:
| Quote: | Hello everyone,
Yes, this may not be the best group to post this message, but I found
some junk, crap and smut in some groups related to linux programming
|
the proper newsgroup is comp.unix.shell. I added it in this posting.
| Quote: | and I got worried that my post would not be seen and be replied in
those places.
Here is part of a short script that will copy fıles containing certain
patterns (in this case "pat1" and "pat2") in different directories to
a single directory whose path is stored in the variable named
"FILEDIR"
for FILE in $(find * |grep 'pat1' | grep 'pat2'); do
cp $FILE $FILEDIR
done
I would like to pass the patterns (1 or more) and the FILEDIR as
command line arguments to the script. However, I could not figure out
how to pass a variÄŸable number of patterns as arguments. If anyone can
suggest a way, I would be grateful. (Teaching me how to combine
patterns in one single grep call will also work)
|
Multiple patterns in grep can be done using egrep or grep -E
i.e.
egrep 'pat1|pat2'
| Quote: |
Best wishes for everyone,
Hurol Aslan
|
Here's my attempt
#!/bin/sh
FILEDIR=${1?'Missing required destination directory'}
shift
PAT="$@"
PAT=$(echo "$@" | tr ' ' '|')
IFS=
find . -type f | egrep "$PAT" | while read line
do
echo cp "$line" "$FILEDIR"
done |
|
| |
|
Back to top |
pk Guest
|
Posted: Tue Nov 18, 2008 8:23 pm Post subject: Re: Need help with a bash script |
|
|
On Tuesday 18 November 2008 14:29, sirlousy@gmail.com wrote:
| Quote: | Thanks for so many responses in such a short time.
As an additional explanation, the filenames did have to contain both
patterns, so an OR would not work for me.
|
So you want a script that takes a variable number of parameters, and
produces a list of all the filenames that match ALL the parameters.
You can thus do:
c=1
for p in "$@"; do
awkp="$awkp /$p/"
[ $c -lt $# ] && awkp="$awkp &&"
c=$((c+1))
done
find . | awk "$awkp"
Note that the above will match the patterns in the full pathnames returned
by find, not just in the filenames. |
|
| |
|
Back to top |
|