Search and replace script - half functional

Forum rules
Before you post please read this

Search and replace script - half functional

Postby bennabiy on Thu Aug 01, 2013 12:32 pm

I am currently working on archiving .WMA recordings to DVD, and need to replace a string of text, including potential spaces, with a different string of text.

If I just wanted to do one search and replace, my code works, but if I want to change the search term, it breaks to not find anything.

Here is my code:

Code: Select all
#!/bin/bash

ARGS=2
E_WRONGARGS=65
END_CONDITION=1
if [ $# -ne "$ARGS" ] # Check for proper no. of command line args.
then
   echo "Usage: `basename $0` "\'text to replace\'" community-name"
   exit $E_WRONGARGS
fi

REPLACE_TEXT=$1
COMMUNITY_NAME=$2
OLDIFS=$IFS

function justlist {
IFS=$(echo -en "\n\b")
OLDREPLACE=$REPLACE_TEXT
for filename in $( ls *"$REPLACE_TEXT"* ); do newname=`echo "$filename" | sed -e 's/'"$REPLACE_TEXT"'/'_"$COMMUNITY_NAME"'/g'`; echo "Change list:  $filename  --->   $newname"; done
REPLACE_TEXT=$OLDREPLACE
IFS=$OLDIFS
}

function whizbang {
IFS=$(echo -en "\n\b")
for filename in $( ls ); do newname=`echo "$filename" | sed -e 's/'"$REPLACE_TEXT"'/'_"$COMMUNITY_NAME"'/g'`; echo "Now changing:  $filename  --->   $newname"; mv "$filename" "$newname"; done
IFS=$OLDIFS
}
quitguage=0
until [ "$quitguage" = "$END_CONDITION" ]
do
act=""   
echo -n "What would you like to do? {list|change|update|quit} "
   read act
   case $act in
      list|List|LIST|l|L)
         justlist
         ;;
      change|Change|CHANGE|c|C)
         whizbang
         ;;
      quit|Quit|QUIT|q|Q)
         echo "Thank you for using this utility!"
         echo         
         quitguage=1
         exit 0         
         ;;
      update|Update|UPDATE|u|U)
         echo -n "Please enter the new search term including single quotes:"
         read upd
         REPLACE_TEXT=$upd
         ;;
      *)    echo "Please select one of the options provided."
         echo "To update the search term, choose update."
         ;;
   esac
done      
exit 0


When run, the initial search finds files in the current directory, lists them, and then repeats. If I list again, it works fine, if I try to update the search term, it does not find anything, if I update the search term back to the original one used on the command line, it still finds nothing.

Thoughts?
bennabiy
Level 1
Level 1
 
Posts: 7
Joined: Thu Aug 01, 2013 11:02 am

Linux Mint is funded by ads and donations.
 

Re: Search and replace script - half functional

Postby WharfRat on Sat Aug 03, 2013 9:41 pm

Maybe I'm missing something here :?
Code: Select all
bill@funlap ~/junk $ ./test.sh test org
What would you like to do? {list|change|update|quit} l
Change list:  test.sh  --->   _org.sh
Change list:  test.sh~  --->   _org.sh~
What would you like to do? {list|change|update|quit} u
Please enter the new search term including single quotes:test
What would you like to do? {list|change|update|quit} l
Change list:  test.sh  --->   _org.sh
Change list:  test.sh~  --->   _org.sh~
What would you like to do? {list|change|update|quit} u
Please enter the new search term including single quotes:org
What would you like to do? {list|change|update|quit} l
Change list:  _org.sh~  --->   __org.sh~
What would you like to do? {list|change|update|quit}

If I quote the new search term e.g., 'test' or "test" then it can't find it
Code: Select all
What would you like to do? {list|change|update|quit} u
Please enter the new search term including single quotes:'test'
What would you like to do? {list|change|update|quit} l
ls: cannot access *'test'*: No such file or directory
What would you like to do? {list|change|update|quit}

A few things I would suggest is change `basename $0` and `echo "$filename" | sed -e 's/'"$REPLACE_TEXT"'/'_"$COMMUNITY_NAME"'/g'` to
$(basename $0) and $(echo "$filename" | sed -e 's/'"$REPLACE_TEXT"'/'_"$COMMUNITY_NAME"'/g')
and change the functions to justlist() {. The function keyword is optional in bash, but might fail in other shells.

Good luck :wink:
Image
User avatar
WharfRat
Level 12
Level 12
 
Posts: 4279
Joined: Thu Apr 07, 2011 8:15 pm

Re: Search and replace script - half functional

Postby bennabiy on Tue Aug 13, 2013 2:56 pm

It is a script to search and replace, but for a specific context ( not just a general search / replace ). Basically I had someone who had a load of files which needed to be renamed, and have text appended in the place of a certain flag in the filename, adding an underscore before the replace.

hence the file 2013.04.10-P01 T-T.wma would then be able to be renamed 2013.04.10-P01_placename.wma

I figured it out, and updated the functionality a little bit.

Code: Select all
#!/bin/bash

ARGS=2
E_WRONGARGS=65
END_CONDITION=1
LOG="$HOME/egad-changelist.txt"
if [ $# -ne "$ARGS" ] # Check for proper no. of command line args.
then
      echo "Usage: $( basename $0 ) "\'text to replace\'" community-name"
   echo ;
   exit $E_WRONGARGS
fi

REPLACE_TEXT=$1
COMMUNITY_NAME=$2
OLDIFS=$IFS

function justlist {
IFS=$(echo -en "\n\b")
OLDREPLACE=$REPLACE_TEXT
for filename in $( ls *"$REPLACE_TEXT"* ); do newname= $( echo "$filename" | sed -e 's/'"$REPLACE_TEXT"'/'_"$COMMUNITY_NAME"'/g' ); echo "Change list:  $filename  --->   $newname"; done
REPLACE_TEXT=$OLDREPLACE
IFS=$OLDIFS
}

function whizbang {
IFS=$(echo -en "\n\b")
for filename in $( ls ); do newname=$( echo "$filename" | sed -e 's/'"$REPLACE_TEXT"'/'_"$COMMUNITY_NAME"'/g' ) ; echo "Now changing:  $filename  --->   $newname"; mv "$filename" "$newname"; done
IFS=$OLDIFS
}
function update {
   echo -n "Which would you like to update? {(S)earch|(R)eplace}"         
   read up
      case $up in
         S|s|search|Search)
            echo "Current search / replace term is: $REPLACE_TEXT"            
            echo -n "Please enter the new search term (Type \\ before a space):"
            read upd
            REPLACE_TEXT="$upd"
            ;;
         R|r|replace|Replace)
            echo "Current replace-with term is:  $COMMUNITY_NAME"            
            echo -n "Please enter the new replace-with term (Type \\ before a space):"
            read upd
            COMMUNITY_NAME="$upd"
            ;;
         *)    echo "Nothing changed! Search=$REPLACE_TEXT   Replace=$COMMUNITY_NAME   "
            ;;
         esac
      }
quitguage=0
until [ "$quitguage" = "$END_CONDITION" ]
do
echo "Working folder is: " `pwd` 
justlist
act=""   
echo -n "What would you like to do? {list|change|update|quit} "
   read act
   case $act in
      list|List|LIST|l|L)
         justlist
         ;;
      change|Change)
         exec 6>&1          
         exec >> $LOG
         echo "Changes are being written for files in:  "`pwd` ; echo;         
         whizbang
         exec 1>&6 6>&-         
         ;;
      quit|Quit|QUIT|q|Q)
         echo "Thank you for using this utility!"
         echo         
         quitguage=1
         exit 0         
         ;;
      update|Update|UPDATE|u|U)
         update
         ;;
      *)    echo "Please select one of the options provided."
         echo "To update the search or replace term, choose update."
         ;;
   esac
done      
exit 0
bennabiy
Level 1
Level 1
 
Posts: 7
Joined: Thu Aug 01, 2013 11:02 am

Re: Search and replace script - half functional

Postby maedox on Sun Oct 13, 2013 3:11 pm

You've fallen into multiple Bash pitfalls.

You need to quote EVERY variable, ALWAYS.
Don't ever do for f in $(ls), use for f in *

Read these:
http://mywiki.wooledge.org/BashPitfalls
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashGuide

And then there's the rename utility:
rename 's/ T.T/_placename/' *.wma
maedox
Level 1
Level 1
 
Posts: 4
Joined: Thu Dec 01, 2011 6:15 pm


Return to Scripts & Bash

Who is online

Users browsing this forum: No registered users and 1 guest