How to search the file contents in multiple subversion repositories? - regex

I've got multiple SVN repositories of different projects which I would like to search for the same search term / regex, but without checking out or updating each project and doing the search manually on each of them.
I'd like to know if it is possible to search the file contents in multiple SVN repositories for some search term (or regex).

Here is a script:
if [[ $# < 2 ]]; then
echo "Usage: $0 REGEX TARGET..."
echo "where REGEX is a regular expression for grep"
echo "and TARGET... is a list of SVN repositories"
exit
fi
regex=$1
shift
for svnroot in $#; do
for path in $(svn ls --recursive $svnroot); do
if [[ $path != */ ]]; then
svn cat $svnroot/$path \
| grep --label="$svnroot/$path" --with-filename $regex
fi
done
done

Related

Bash string manipulation regex or string indexing

I have two possible artifacts, which I need to modify with a basch script.
Artifacts before manipulation are following
tesla-server-1.1.1-develop#34.tgz
tesla-server-1.1.1-master#34.tgz
After I run my regex on them, they should look the following
tesla-server-1.1.1-develop.tgz
tesla-server-1.1.1.tgz
What I have is the following
#!/bin/env bash
branch=master or develop
if [[ "${branch}" == "develop" ]]; then
artifact="tesla-server-1.1.1-develop#34.tgz"
new_artifact `expr match "$artifact" '(.+develop|.tgz)'`
cp artifact new_artifact
elif [[ "${branch}" == "master" ]]; then
artifact="tesla-server-1.1.1-master#34.tgz"
new_artifact `expr match "$artifact" '(.+master|.tgz)'`
cp artifact new_artifact
fi
Any help would be greatly appreciated, either using regex og string indexing
Using sed you can do:
file='tesla-server-1.1.1-master#34.tgz'
cp "$file" $(sed -E 's/(-master)?#[0-9]+//' <<< "$file")
This will copy given file to tesla-server-1.1.1.tgz

ShellScript - IF handling filename pattern

I have a directory in UNIX which has a thousands of .TGZ compressed files, they follow this pattern :
01.red.something.tgz
02.red.something.tgz
03.red.anything.tgz
04.red.something.tgz
01.blue.something.tgz
02.blue.everything.tgz
03.blue.something.tgz
04.blue.something.tgz
01.yellow.something.tgz
02.yellow.blablathing.tgz
03.yellow.something.tgz
04.yellow.something.tgz
They are using a large amount from the filesystem,and i need to list them without extract the file itself. Actually it'll take some time, so i believe this shellscript will fit the need. I'm kinda new to Shellscript, i'm learning so i made this .sh
$pattern = "red"
for file in *.tgz
do
if [[ ${file} == '...${pattern}.*.tgz' ]]; then
echo" ==> ${file} match the pattern and the output dir is : out/"
tar -tf $file > ./out/$file
else
echo "${file} Doesn't match the pattern"
fi
done
But i've made something wrong in the if part,and even when the pattern is matched, i've got the 'Doesn't match the pattern' message.
I Know it's kinda simple if,but i can't understand why this fella doesn't work. I'd be thankfull if you guys can explain why this doesn't work.
Thank you.
you need to watch out for spaces when you create varibales in bash, in if there should not be ' - single quotes or " - double quotes if you want to match on regex, use: if [[ ${file} == ${regEx} ]];
Test:
$ ls *.tgz
01.red.something.tgz 01.yellow.something.tgz
$ ./t.sh
==> 01.red.something.tgz match the pattern and the output dir is : out/
01.yellow.something.tgz Doesn't match the pattern
$ cat t.sh
#!/bin/bash
pattern="red"
regEx="*.${pattern}.*.tgz"
for file in *.tgz
do
if [[ ${file} == ${regEx} ]]; then
echo " ==> ${file} match the pattern and the output dir is : out/"
#tar -tf $file > ./out/$file
else
echo "${file} Doesn't match the pattern"
fi
done

bash ~ How to search through files in a directory

I have a list of files
shopping-list.txt
our-shopping-list.txt
test.txt
my-test.txt
I want to run myscript shopping and get the two files that have the word shopping. I want to run myscript our list and get just the one file.
at the moment I have this
if [[ $fs =~ .*${*}*.* ]]; then
echo $fs
fi
It works a bit, but it would not give me our-shopping-list if each variable has a gap ie. myscript our list it would work if I typed myscript our - list
I have a big list of files and want to find the one I need by guessing the name
my attempt to apply #pacholik's code
snippetdir="~/my_snippets/"
for filename in $snippetdir*; do
file=`basename "$filename"`
fs=${file%.*}
for i in ${*}; do
for j in *${i}*; do
if [[ $fs =~ .*$j*.* ]]; then
echo $fs
fi
done
done
done
Here's a simple brute-force loop.
for file in *; do
t=true
for word in "$#"; do
case $file in
*"$word"*) ;;
*) t=false; break;;
esac
done
$t && echo "$file"
done
I believe this should be portable to any POSIX shell, and potentially beyond (old Solaris etc).
Using just bash expansion (only you have to evaluate twice). Bash join from here.
files=`IFS=* eval 'echo *"${*}"*'`
Then you can iterate over $files
for i in $files; do
echo $i
done

Linking directories inside directories in Bash

My script processes files.lst and it has a loop that looks like this
while read src_column dest_column; do
if [[ -d $src ]]; then
src="../../default/$src_column/*"
else
src="../../default/$src_column"
fi
pushd $dest
ln -s $src .
popd
done < files.lst
files.lst
#~source~ ~destination~
data dir1
default/def1.txt new1.txt
data dir2/dir22/dir222
default/def1.txt dir2/dir22/dir222/new1.txt
default dir2/dir22
default/def2.txt dir2/dir22/ne2.txt
The cases should be like this:
if destinations are dir2/dir22/dir222 or dir2/dir22/dir222/new1.txt
the starting prefix of $src should be ../../../../default
if destinations are dir2/dir22 or dir2/dir22/new2.txt
the starting prefix of $src should be ../../../default
if destinations are dir2 or dir2/new2.txt
the starting prefix of $src should be ../../default
The problem is I don't know how I will count the directories how deep they are. What approach should I do? I am thinking of regex but I got no idea how I'll use it.
Using sed to calculate the paths...:
while read src_column dest_column; do
if [[ -d $src ]]; then
dest_column="$dest_column/"
fi
src_prefix="$(sed -r 's|/[^/]*$|/|; s|//*|/|g; s|[^/]+|..|g' <<< "./$dest_column")default"
# sed command details:
# First expression: strip out any file.txt from $dest_column
# 2nd expression: Change duplicate / to single / (e.g. a/b//c// to a/b/c
# Last expression: Change any path to `..`
#Finally append the missing ../default.
if [[ -d $src ]]; then
src="$src_prefix/$src_column/*"
else
src="$src_prefix/$src_column"
fi
pushd $dest
ln -s $src .
popd
done < files.lst

Bash Script sed command not working correctly with file passed through command line

Problem
As I am trying to write a script to rename massive files according to some regex requirement, the command work ok on my iTerm2 succeeds but the same command fails to do the work in the script.
Plus some of my file names includes some Chinese and Korean characters.(don't know whether that is the problem or not)
code
So My code takes three input: Old regex, New regex and the files that need to be renamed.
Here is not code:
#!/bin/bash
# we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
cat << HELP
ren -- renames a number of files using sed regular expressions USAGE: ren 'regexp'
'replacement' files...
EXAMPLE: rename all *.HTM files into *.html:
ren 'HTM' 'html' *.HTM
HELP
exit 0
fi
OLD="$1"
NEW="$2"
# The shift command removes one argument from the list of
# command line arguments.
shift
shift
# $# contains now all the files:
for file in "$#"; do
if [ -f "$file" ] ; then
newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
if [ -f "$newfile" ]; then
echo "ERROR: $newfile exists already"
else
echo "renaming $file to $newfile ..."
mv "$file" "$newfile"
fi
fi
done
I register the bash command in the .profile as:
alias ren="bash /pathtothefile/ren.sh"
Test
The original file name is "제01과.mp3" and I want it to become "第01课.mp3".
So with my script I use:
$ ren "제\([0-9]*\)과" "第\1课" *.mp3
And it seems that the sed in the script has not worked successfully.
But the following which is exactly the same, works to replaces the name:
$ echo "제01과.mp3" | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g
Any thoughts? Thx
Print the result
I have make the following change in the script so that it could print the process information:
newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
echo "The ${file} is changed to ${newfile}"
And the result for my test is:
The 제01과.mp3 is changed into 제01과.mp3
ERROR: 제01과.mp3 exists already
So there is no format problem.
Updating(all done under bash 4.2.45(2), Mac OS 10.9)
Testing
As I try to execute the command from the bash directly. I mean with the for loop. There is something interesting. I first stored all the names into a files.txt file using:
$ ls | grep mp3 > files.txt
And do the sed and bla bla. While single command in bash interactive mode like:
$ file="제01과.mp3"
$ echo $file | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g
gives
第01课.mp3
While in the following in the interactive mode:
files=`cat files.txt`
for file in $files
do
echo $file | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g
done
gives no changes!
And by now:
echo $file
gives:
$ 제30과.mp3
(There are only 30 files)
Problem Part
And I tried the first command which worked before:
$ echo $file | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g
It gives no changes as:
$ 제30과.mp3
So I create a new newfile and tried again as:
$ newfile="제30과.mp3"
$ echo $newfile | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g
And it gives correctly:
$第30课.mp3
WOW ORZ... Why! Why ! Why! And I try to see whether file and newfile are the same, and of course, they are not:
if [[ $file == $new ]]; then
echo True
else
echo False
fi
gives:
False
My guess
I guess there are some encoding problems , but I have found non reference, could anyone help? Thx again.
Update 2
I seem to understand that there are a huge difference between string and the file name. To be specific, it I directly use a variable like:
file="제30과.mp3"
in the script, the sed works fine. However, if the variable was passed from the $# or set the variable like:
file=./*mp3
Then the sed fails to work. I don't know why. And btw, mac sed has no -r option and in ubuntu -r does not solve the question I mention above.
Some errors combined:
In order to use groups in a regex, you need extended regex -r in sed, -E in grep
escaping correctly is a beast :)
Example
files="제2과.mp3 제30과.mp3"
for file in $files
do
echo $file | sed -r 's/제([0-9]*)과\.mp3/第\1课.mp3/g'
done
outputs
第2课.mp3
第30课.mp3
If you are not doing this as a programming project, but want to skip ahead to the part where it just works, I found these resources listed at http://www.tldp.org/LDP/GNU-Linux-Tools-Summary/html/x4055.htm:
MMV (and MCP, MLN, ...) utilities use a specialized syntax to perform bulk file operations on paths. (http://linux.maruhn.com/sec/mmv.html)
mmv before\*after.mp3 Before\#1After.mp3
Esomaniac, a Java alternative that also works on Windows, is apparently dead (home page is parked).
rename is a perl script you can download from CPAN: https://metacpan.org/release/File-Rename
rename 's/\.JPG$/.jpg/' *.JPG