Append part of a file name to another file name - bash

I have a long file name that I'm converting and a creating a new file from it. Im having a bad brain lapse and cant figure out how to take the time stamp from the original file and append it to the end of my new file.
heres an example of the original file name, the 20171005084554 is the part i want to append to my new file.
527448423osel5108_k8lx2og.527448423_20171005-095125.20171005084554
I run my script
#/bin/sh -x
grep "COLUMN:WM\|COLUMN:Vendor" ${1} | sed 's/^COLUMN://' | sed 's/\.//g' > cust_$(date +%Y%m%d)_converted.txt
grep "DATA:" ${1} | sed 's/^DATA://' >> cust_$(date +%Y%m%d)_converted.txt
# mv ${1} processed/
Where i have $(date +%Y%m%d) is where i want to the other time stamp.
Anyone have any unix / shell magic to help me out?

Using just parameter expansion:
#!/usr/bin/env bash
ext=${1##*.} # ${1: -14} also possible
file=cust_${ext}_converted.txt
echo "$file"
Output:
cust_20171005084554_converted.txt

Related

How to find lines with current date with %d-%h-%Y format assigned to a variable in all files

I have a directory under which i have many access files like:
access
access87681
access98709
Now i am trying grep all those lines with current date in format +%d-%h-%Y.
I have written like below:
tm1=$(date '+%d-%h-%Y')
sed -n '/$tm1/p' $dir/access* > $loc/OUD_Req_Res_matrix_data
I am trying to grep all $dir/access* files with $tm1 which is current date in above date format and pushing them into output file $loc/OUD_Req_Res_matrix_data.
the above code is not working. Please suggest
With tm1=$(date '+%d-%h-%Y') and access-files without spaces, you can use:
sed -n "/${tm1}/p" $dir/access*
When the date has slashes, the sed command would break.
You can escape the slashes with
sed 's#/#\\/#g' <<< "$tm1"
Use this in your command:
sed -n "/$(sed 's#/#\\/#g' <<< "$tm1")/p" $dir/access*

Add file date to file name in bash

I'm looking for a programmatic way to add a file's date to the filename. I'm on a Mac, Yosemite (10.10).
Using Bash, I have put a fair amount of effort into this, but just too new to get there so far. Here's what I have so far:
#!/bin/bash
#!/bin/bash
(IFS='
'
for x in `ls -l | awk '{print$9" "$7"-"$6"-"$9}'`
do
currentfilename=$(expr "$x" : '\($substring\)')
filenamewithdate=$(expr "$x" : '.*\($substring\)')
echo "$currentfilename"
echo "$filenamewithdate"
done)
The idea here is to capture detailed ls output, use awk to capture the strings for the columns with the filename ($9), and also date fields ($7 and $6), then loop that output to capture the previous filename and new filename with the date to mv the file from old filename to new. The awk statement adds a space to separate current filename from new. The echo statement is there now to test if I am able to parse the awk ouput. I just don't know what to add for $substring to get the parts of the string that are needed.
I have much more to learn about Bash scripting, so I hope you'll bear with me as I learn. Any guidance?
Thanks.
Looking at the stat man page, you'd want:
for file in *; do
filedate=$(stat -t '%Y-%m-%dT%H:%M:%S' -f '%m' "$file")
newfile="$file-$filedate"
echo "current: $file -> new: $newfile"
done
Adjust your preferred datetime format to your taste.
You could save a line with
for file in *; do
newfile=$(stat -t '%Y-%m-%dT%H:%M:%S' -f '%N-%m' "$file")

Bash script to replace info in file

I have a new file that I created that has a list of all directories that have a particular file:
$ find . -name "bun.biscuts" > TREE.temp
This writes all of the correct info I need to the new temp file.
I am having trouble writing a bash script using sed to replace emails in the TREE.temp file.
This is what I have so far:
#!/bin/bash
#set -x
echo Start!
for bun.biscuts in (TREE.temp)
do
sed -i 's/EMAIL1/EMAIL2/g';
done
Any help would be amazing!
gniourf_gniourf's comment is right; you don't need to use a temporary file and loop to do this. But if you want to, you could do it like this:
while read; do
sed -i 's/EMAIL1/EMAIL2/g' "$REPLY"
done < TREE.temp
which performs the sed operation on the filename on each line of the file. $REPLY is the default variable name that each line is written to by read. You can change the variable name by doing read var instead - then each line will be written to $var.
You can use only one sed command:
sed -i.bak 's/EMAIL1/EMAIL2/g' TREE.temp
If you have node on the computer you can npm install -g rexreplace and then
rexreplace 'email1' 'email2' TREE.tmp

How to remove a part of a string with variable?

I just got into bash so I decided to write my first script. To give you a little background I want to write a script that will back up my Documents folder onto a USB stick whenever I connect the USB stick. (I am aware that software like this exists).
I have two strings at the beginning of the script:
directoryPath="/Users/USER/Documents" # Folder I want to backup
backupPath="/Volumes/backMeUp/main" # Where I want the folder to backup
For loops gives me absolute path to a file like this
/Users/USER/Documents/Comics/Bleach/Volume 004/bleach_031.zip
Until now I was using sed like this
newPath=`echo "$file" | sed "/Users\/USER\/Documents/s//Volumes\/backMeUp\/main/"`
But since I want my script to be more "open" and other-user-friendly I want to get rid of this line and make it some other way.
I also tried this with different syntax
echo $file | sed -e "s/$directoryPath/$backupPath/"
but with no luck.
My question is how can I remove part of a string with $directoryPath and replace it with $backupPath?
basename (and dirname) are your friend(s).
Something like this:
#!/bin/bash
directoryPath="/Users/rojcyk/Documents" # Folder I want to backup
backupPath="/Volumes/backMeUp/main" # Where I want the folder to backup
f=$(basename '/Users/rojcyk/Documents/Comics/Bleach/Volume 004/bleach_031.zip')
echo ${backupPath}/${f}
Updated
#!/bin/bash
directoryPath="/Users/rojcyk/Documents" # Folder I want to backup
backupPath="/Volumes/backMeUp/main" # Where I want the folder to backup
f='/Users/rojcyk/Documents/Comics/Bleach/Volume 004/bleach_031.zip'
# delete shortest match of substring from front of string
new_f=${f#$directoryPath}
echo ${backupPath}${new_f}
Output:
/Volumes/backMeUp/main/Comics/Bleach/Volume 004/bleach_031.zip
Read more about bash string operations here
With bash:
directoryPath="/Users/rojcyk/Documents"
backupPath="/Volumes/backMeUp/main"
f="/Users/rojcyk/Documents/Comics/Bleach/Volume 004/bleach_031.zip"
echo "${backupPath}/${f#$directoryPath}"
Produces
/Volumes/backMeUp/main//Comics/Bleach/Volume 004/bleach_031.zip
The double slash in the middle is OK. If you don't want it: "${backupPath}/${f#$directoryPath/}"
is this what you want?
kent$ cat t
$foo$bar$blah
kent$ sed 's/\$foo/\$xxx/g' t
$xxx$bar$blah
or this?
kent$ echo $foo
/f/o/o
kent$ echo $bar
/b/a/r
kent$ cat t
something /f/o/o
kent$ sed "s:$foo:$bar:" t
something /b/a/r
sed -e "s/$directoryPath/$backupPath/"
You're on the right path, just need to manipulate the two path variables first.
The contents of $directoryPath is /Users/rojcyk/Documents, so your sed command is coming out as sed -e "s//Users/rojcyk/Documents//Volumes/backMeUp/main/". You need to escape the directory slashes so they don't affect the sed command.
Try this:
directoryPathEscaped=`echo $directoryPath | sed -e "s/\\//\\\\\\\\\//g"`
backupPathEscaped=`echo $backupPath| sed -e "s/\\//\\\\\\\\\//g"`
# At this point, directoryPathEscaped is equal to "\/Users\/rojcyk\/Documents"
# Now you can do your original command line, with the new variables.
sed -e "s/$directoryPathEscaped/$backupPathEscaped/"

BASH shell scripting file parsing [newbie]

I am trying to write a bash script that goes through a file line by line (ignoring the header), extracts a file name from the beginning of each line, and then finds a file by this name in one directory and moves it to another directory. I will be processing hundreds of these files in a loop and moving over a million individual files. A sample of the file is:
ImageFileName Left_Edge_Longitude Right_Edge_Longitude Top_Edge_Latitude Bottom_Edge_Latitude
21088_82092.jpg: -122.08007812500000 -122.07733154296875 41.33763821961143 41.33557596965434
21088_82093.jpg: -122.08007812500000 -122.07733154296875 41.33970040427444 41.33763821961143
21088_82094.jpg: -122.08007812500000 -122.07733154296875 41.34176252364274 41.33970040427444
I would like to ignore the first line and then grab 21088_82092.jpg as a variable. File names may not always be the same length, but they will always have the format digits_digits.jpg
Any help for an efficient approach is much appreciated.
This should get you started:
$ tail -n +2 input | cut -f 1 -d: | while read file; do test -f $dir/$file && mv -v $dir/$file $destination; done
You can construct a script that will do something like this, then simply run the script. The following command will give you a script which will copy the files from one place to another, but you can make the script generation more complex simply by changing the awk output:
pax:~$ cat qq.in
ImageFileName Left_Edge_Longitude Right_Edge_Longitude
21088_82092.jpg: -122.08007812500000 -122.07733154296875
21088_82093.jpg: -122.08007812500000 -122.07733154296875
21088_82094.jpg: -122.08007812500000 -122.07733154296875
pax:~$ awk -F: '/^[0-9]+_[0-9]+.jpg:/ {
printf "cp /srcdir/%s /dstdir\n",$1
} {}' qq.in
cp /srcdir/21088_82092.jpg /dstdir
cp /srcdir/21088_82093.jpg /dstdir
cp /srcdir/21088_82094.jpg /dstdir
You capture the output of that script (the last three lines) to another file then that file is your script for doing the actual copies.

Resources