Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

HP-UX *** B.11.31 U ia64 ***unlimited-user license

I want to move a file in the current directory called abc.txt to a directory called ./begperl. While I do so I want the moved version of the file to be named as ab.txt.What I want is to remove a predefined string from the filename and move it, and delete the original file based on one more third variable=Y/N. I have tried the below oneliners in vain.

awk -v name=abc.txt -v dir=begperl 'BEGIN{ renamed_var=substr("c", "", name);system("mv " name  "./"dir/renamed_var)}' 

awk -v name=abc.txt -v dir=begperl 'BEGIN{ renamed_var=substr("c", "", name); print renamed_var}'

awk -v name=abc.txt -v dir=begperl 'BEGIN{ print substr("c", "", name) }'


awk -v name=abc.txt -v dir=begperl -v variable_two=substr("c", "", name){print variable_two}' 


awk -v name=abc.txt -v dir=begperl -v variable_two=substr("c", "", name){print variable_two}'

The only one liner that I got working is

awk -v name=abc.txt -v dir=begperl 'BEGIN{ system("mv " name " ./"dir)}' 

Immense thanks

share|improve this question
1  
You have a couple of issues with your code. awk's substr() function expects a string as first argument and an index and a length as second and (optional) third argument. I also see a general design problem; you are doing primitive string operations and then invoke a shell (by using system(). Instead this sort of task could better be done completely in a shell. –  Janis Apr 1 at 11:39

3 Answers 3

Why are you using awk for this? If you have both the original and the target name, why not just mv abc.txt begperl/ab.txt?

If you don't have the target name and just want to remove a character from the original, you can do it in the shell. Again, no need for awk:

file="abc.txt"; mv "$file" begperl/"${file//c}"

That will remove all occurrences of c from $file. To remove the first one only, use

file="abc.txt"; mv "$file" begperl/"${file/c}"

Alternatively, you could do

mv abc.txt begperl/"$(echo "abc.txt" | sed 's/c//')"
share|improve this answer
    
need one liner. Remove a string from filename, copy to some other directory, delete original based on the value of a variable. Looked like awk could do it. –  user3146086 Apr 1 at 11:57
    
Some shells do not allow such substitution like ${file/c}. In the case can help ${file%c*}${file#*c} –  Costas Apr 1 at 11:59
    
@Costas good point about that not being present in all shells. However, your alternatives remove everything after the last c or everything up to the first c. Neither is what the OP requested. –  terdon Apr 1 at 12:07
    
@user3146086 Well, those are one-liners really. Anyway, see updated for another way. Launching awk with an internal system call is just overkill. –  terdon Apr 1 at 12:08

You need the sub (substitute) rather than the substr (substring) command: compare

$ awk -v name="abc.txt" 'BEGIN {substr("c","",name) ; print name}'
abc.txt

with

$ awk -v name="abc.txt" 'BEGIN {sub("c","",name) ; print name}'
ab.txt

However unless you are doing this as a programming exercise to learn awk, there really is no reason not to use your shell for things like this e.g. in bash:

newname="${name%c.*}.${name##*.}"

forms a string from name with the shortest trailing match starting with c. removed, concatenated with the dot extension formed by removing the longest portion matching up to .

share|improve this answer
    
can we do it without echo? –  user3146086 Apr 1 at 11:46
    
@user3146086 afaik awk needs to read something - either from a file, or from standard input: the piped echo is just a way to provide that. But TBH unless you are just doing this as a programming exercise, there is no reason at all to use awk here. –  steeldriver Apr 1 at 11:51
    
If you use BEGIN term there is no need to read from anywhere: awk -v name="abc.txt" 'BEGIN{sub("c","",name) ; print name}' –  Costas Apr 1 at 13:10
    
@Costas doh! thanks, answer amended accordingly –  steeldriver Apr 1 at 13:51

I am the OP. I dont think this is as easy as I thought it would be to be implemented in a one liner. I think I wil work on this one liner later(Or never ;-))

#!/usr/bin/ksh
ORIGINAL_FILE_NAME_WITH_PATH_VARIABLE=$1
REMOVE_STRING_VARIABLE=$2
DELETE_ORIGINAL_FILE_NAME_WITH_PATH_VARIABLE=$3
if [[ $# -ne 3 ]]
then
echo "Script requires three parameters. First:Filename with path. Second:String to remove from filename. Third:Y or N to delete file"
exit 1
fi
ORIGINAL_FILE_NAME_VARIABLE=`echo  ${ORIGINAL_FILE_NAME_WITH_PATH_VARIABLE} | awk -F '/' '{print $NF}'`
#echo ${ORIGINAL_FILE_NAME_VARIABLE}
AMENDED_FILE_NAME_VARIABLE=`echo ${ORIGINAL_FILE_NAME_VARIABLE} | sed "s/${REMOVE_STRING_VARIABLE}//g"`
#echo ${AMENDED_FILE_NAME_VARIABLE}
ORIGINAL_FILE_LOCATION_DIR=`echo ${ORIGINAL_FILE_NAME_WITH_PATH_VARIABLE} | awk 'BEGIN{FS=OFS="/"}{$NF=""; NF--; print}'`
if [[ -f ${ORIGINAL_FILE_LOCATION_DIR}/${AMENDED_FILE_NAME_VARIABLE} ]]
then
AMENDED_FILE_NAME_VARIABLE=${AMENDED_FILE_NAME_VARIABLE}_$$_$$
fi
echo ${ORIGINAL_FILE_NAME_VARIABLE}|grep -q ${REMOVE_STRING_VARIABLE}
if [[ $? -ne 1 ]] 
then
cp ${ORIGINAL_FILE_NAME_WITH_PATH_VARIABLE} ${ORIGINAL_FILE_LOCATION_DIR}/${AMENDED_FILE_NAME_VARIABLE}
if [[ ${DELETE_ORIGINAL_FILE_NAME_WITH_PATH_VARIABLE} = 'y' || ${DELETE_ORIGINAL_FILE_NAME_WITH_PATH_VARIABLE} = 'Y' ]]
then
rm ${ORIGINAL_FILE_NAME_WITH_PATH_VARIABLE}
fi
fi

But I really thought this was possible in a one liner. I am the OP.Comments?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.