How to get everything after an extension unix - unix

I have a file name like
filename.txt.zip_20180202_30291_233
In script variable i will have filename in a variable and extension in variable
like
echo $fileprefix
filename
echo $filesuffix
.txt.zip
How do i rename the file to below one ? Moving everything after extension to before extension ? (Note: there could be any numbers after extension )
filename_20180202_30291_233.txt.zip

#!/bin/sh
prefix='filename'
suffix='.txt.zip'
name='filename.txt.zip_20180202_30291_233'
newname="$prefix${name#$prefix$suffix}$suffix"
echo mv "$name" "$newname"
This would output
mv filename.txt.zip_20180202_30291_233 filename_20180202_30291_233.txt.zip
The parameter substitution ${name#$prefix$suffix} removes $prefix$suffix, i.e. filename.txt.zip, from the start of $name, which gives you _20180202_30291_233. This is then prepended with $prefix and appended with $suffix to create $newname.
Looping over all files that matches "$prefix$suffix"* in the current directory and renaming all:
for name in "$prefix$suffix"*; do
newname="$prefix${name#$prefix$suffix}$suffix"
echo mv "$name" "$newname"
done
The echo is there for protection. Remove it once you are certain the code will do the right thing.

file_orig=filename.txt.zip_20180202_30291_233
fileprefix=filename
filesuffix=.txt.zip
file="${file_orig#$fileprefix}"
file="${file#$filesuffix}"
file="$fileprefix$file$filesuffix"
echo "$file"
filename_20180202_30291_233.txt.zip
https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

Related

Look for file ksh

I am trying to learn unix. I wanted to set up a sort of file watcher that looks for files and returns the file names so i can move them from source to processing folder to process. It echos File Found I just cannot figure out how to capture the file name.
#determines if file exists
if [ -f * ]; then
echo "File found"
else
echo "File not Found"
fi
# returns file to array
#Needs name still
NewFiles[0] =
#output what what found in 0 index
echo "Found File"
echo NewFiles[0]
Assuming the files have no fancy names (embedded spaces or similar), you might use that approach:
set -- *
[ $# -gt 0 ] && {
echo Found file
echo $1
}

sub string in unix on a character

I have file names inside a directory in unix as:
code1_abc.txt
code2_xyz.txt
code1_pqr.txt
I am looping over all files in this director to do some stuff on each files:
for myFile in $(ls $INPUT_DIR/* | xargs -n 1 basename)
do
echo $myFile
done
However, now I want to split the file name and want to get the part before the underscore i.e. code1, code2, code3
for myFile in $(ls $INPUT_DIR/* | xargs -n 1 basename)
do
echo $myFile
codeForCurrentFile= // want code1 here using myFile value
echo $codeForCurrentFile // should echo code1, code2, code3 respectively
done
How to do this? I am using korn shell.
Thanks for reading!
Use ksh pattern substitution to replace the underscore and anything after it with nothing (effectively delete):
echo ${myFile//_*/}
For your example:
codeForCurrentFile=${myFile//_*/}
More info here (see section 4.5.4): http://docstore.mik.ua/orelly/unix3/korn/ch04_05.htm
You can do this by calling out to an external program, regardless of the shell in use (provided it supports output capture of external programs, of course), such as with the following transcript:
pax$ fspec=code1_abc
pax$ echo $fspec
code1_abc
pax$ pre=`echo $fspec | cut -d_ -f1` ; echo $pre
code1
pax$ post=`echo $fspec | cut -d_ -f2` ; echo $post
abc
There are a wide variety of tools you can use to achieve this, cut (as above, probably the simplest), awk, sed and so on.
This has the disadvantage of kicking up external processes, something that should be okay provided you're not doing it many times per second. If it's something that needs to be fast, you're better off using shell-specific internal methods, such as:
ksh:
fspec=code1_abc
pre=${fspec//_*/}
post=${fspec//*_/}
bash:
fspec=code1_abc
pre=${fspec%%_*}
post=${fspec#*_}
csh:
set fspec = code1_abc
set arr = ( $fspec:as/_/ / )
set pre = $arr[1]
set post = $arr[2]

How to insert a file into this code but not a string

This is the code:
#!/bin/bash
title='Unix Shell Programming'
read search_word
if [[ $title =~ $search_word ]]
then
echo Yes - matchli
else
echo No - match
enter code here
fi
I want to substitute the $title to a file called emplist. Is it possible? And how can I do that? Thank you!
add these lines in your shell script,
echo "enter file name with extension"
read fname
cat $fname
You can use grep like this:
if grep -q "$search_word" emplist
then
# $search_word was found inside the file emplist

how to copy the dynamic file name and append some string while copying into other directory in unix

I have many files like ABC_Timestamp.txt , RAM_Timestamp.txthere timestamp will be different everytime. I want to copy this file into other directory but while copying I want append one string at the end of the file , so the format will be ABC_Timestamp.txt.OK and RAM_Timestamp.txt.OK. How to append the string in dynamic file. Please suggest.
My 2 pence:
(cat file.txt; echo "append a line"; date +"perhaps with a timestamp: %T") > file.txt.OK
Or more complete for your filenames:
while sleep 3;
do
for a in ABC RAM
do
(echo "appending one string at the end of the file" | cat ${a}_Timestamp.txt -) > ${a}_Timestamp.txt.OK
done
done
Execute this on command line.
ls -1|awk '/ABC_.*\.txt/||/RAM_.*\.txt/
{old=$0;
new="/new_dir/"old".OK";
system("cp "old" "new); }'
Taken from here
You can say:
for i in *.txt; do cp "${i}" targetdirectory/"${i}".OK ; done
or
for i in ABC_*.txt RAM_*.txt; do cp "${i}" targetdirectory/"${i}".OK ; done
How about first dumping the names of the file in another file and then moving file one by one.
find . -name "*.txt" >fileNames
while read line
do
newName="${line}appendText"
echo $newName
cp $line $newName
done < fileNames

How to quote strings in file names in zsh (passing back to other scripts)

I have a script that has a string in a file name like so:
filename_with_spaces="a file with spaces"
echo test > "$filename_with_spaces"
test_expect_success "test1: filename with spaces" "
run cat \"$filename_with_spaces\"
run grep test \"$filename_with_spaces\"
"
test_expect_success is defined as:
test_expect_success () {
echo "expecting success: $1"
eval "$2"
}
and run is defined as:
#!/bin/zsh
# make nice filename removing special characters, replace space with _
filename=`echo $# | tr ' ' _ | tr -cd 'a-zA-Z0-9_.'`.run
echo "#!/bin/zsh" > $filename
print "$#" >> $filename
chmod +x $filename
./$filename
But when I run the toplevel script test_expect_success... I get cat_a_file_with_spaces.run with:
#!/bin/zsh
cat a file with spaces
The problem is the quotes around a file with spaces in cat_a_file_with_spaces.run is missing. How do you get Z shell to keep the correct quoting?
Thanks
Try
run cat ${(q)filename_with_spaces}
. It is what (q) modifier was written for. Same for run script:
echo -E ${(q)#} >> $filename
. And it is not bash, you don't need to put quotes around variables: unless you specify some option (don't remember which exactly)
command $var
always passes exactly one argument to command no matter what is in $var. To ensure that some zsh option will not alter the behavior, put
emulate -L zsh
at the top of every script.
Note that initial variant (run cat \"$filename_with_spaces\") is not a correct quoting: filename may contain any character except NULL and / used for separating directories. ${(q)} takes care about it.
Update: I would have written test_expect_success function in the following fashion:
function test_expect_success()
{
emulate -L zsh
echo "Expecting success: $1" ; shift
$#
}
Usage:
test_expect_success "Message" run cat $filename_with_spaces

Resources