CyberKeeda In Social Media
Showing posts with label #!/bin/bash. Show all posts
Showing posts with label #!/bin/bash. Show all posts

Upload File from Local to S3 Bucket using CURL

 

Upload data to S3 bucket using CURL.

This guide aka shell script will help you to upload files into S3 without installing AWS SDK, Python Boto or AWS CLI.


Script's README section has most of the usage defined, high level things script can do.

  • Copy files from a specific directory between specific range dates.
  • Copy specific files with search filer.
  • Script logs all the file copy into file with time stamp. 
  • Reinitiate is supported without re-write


#!/bin/bash
#
# Parameters
# $1 => Directory/Folder to search file.
# $2 => AWS Bucket subdirectories 
#       Example -- myAWSs3bucket/folderA/FolderB/FolderC
#              1.) In case one want to put files in folderA, use folderA as $2
#                  2.) In case one want to put files in folderB, use folderA/folderB as $2
#                  3.) In case one want to put files in folderC, use folderA/folderB/folderC as $2
# $3 => Existense of file from Start date in format YYYYMMDD 
#       Example --
#                  1.) 20210104 -> 4th January 2021
#                  2.) 20201212 -> 12th December 2020
# $4 => Existense of file upto end date in format YYYYMMDD
#       Example --
#                  1.) 20200322 -> 22nd March 2020
#                  2.) 20201212 -> 12th December 2020
# $5 => File Filter 
#       Example -- We need only specific files from a folder.
#                  1.) 20200122_data_settlement.txt --> Use $5 as *_data_settlement.txt
#                  2.) salesdata-20201215100610.txt --> Use $5 as salesdata-*
#      
# Task - Find similar 20200122_data_settlement.txt on location /usr/data/
#        File existence date range 20200322 (22nd March 2020) to 20210104 (4th January 2021)
#        Copy it to AWS S3 bucket's subfolder named as folderA 
#
#     
# Syntax -  ./copy_data_to_S3_via_Curl.sh <LocalFolderLocation> <S3BUCKET-DIRECTORY> <STARTDATE> <ENDDATE> <FILEFILTER>
#
# Usage
#
#        1.) With File Filter
#         ./copy_data_to_S3_via_Curl.sh /usr/data folderA 20200322 20210104  '*data_settlement.txt'
#
#        2.) Without File Filter
#         ./copy_data_to_S3_via_Curl.sh /usr/data folderA 20200322 20210104  
#        
#    3.) Reinitiate left upload
#
#         ./copy_data_to_S3_via_Curl.sh 1 folderA
#
#
#  Flow 
#  1.) Script use find command to find all the files with parameters and write it to a file "/tmp/file_inventory.txt"
#  2.) For Loop is being used further ti read file inputs and do S3 operations using HTTPS API
#  3.) Script keeps removing the entries from inventory file after a successful upload.
#  4.) Script writes the successful and failed upload status within log file "/tmp/file_copy_status.log"
#  5.) Incase we want to interrupt and upload the remaining files later, comment line no 62
#        62 find $1 -newermt $3 \! -newermt $4   -iname "$5" >> $inventory
#      To avoid confusion run the script with same paramter.
#
#
# Author: Jackuna
#

# Bucket Data
bucket="mys3bucket-data"
s3_access_key="AKgtusjksskXXXXTQTW"
s3_secret_key="KSKKSIS HSNKSLS+ydRQ3Ya37A5NUd1V7QvEwDUZR"

# Files
inventory="/tmp/file_inventory.txt"
logme="/tmp/file_copy_status.log"


if  [ $# == 2 ]; then
  echo "`date` -  Initiating left file upload from old inventory " >> $logme

elif [ $# -eq 5 ]; then
  truncate -s 0 $inventory
  find $1 -newermt $3 \! -newermt $4   -iname "$5" >> $inventory
  echo "`date` - Initiating all file that contains string $5 and found between $3 - $4  upload from new inventory " >> $logme

elif [ $# -eq 4 ]; then
  truncate -s 0 $inventory
  find $1 -newermt $3 \! -newermt $4  >> $inventory
  sed -i 1d $inventory
  echo "`date` - Initiating all file found between $3 - $4  upload from new inventory " >> $logme

else
  echo " Some or all arguments Missing from CLI"
  echo " Usage :  ./copy_data_to_S3_via_Curl.sh <LocalFolderLocation> <S3BUCKET-DIRECTORY> <STARTDATE> <ENDDATE> <FILEFILTER>"
  echo " Open Script README section"
  exit 1
fi

file_list=`cat $inventory`
total_file_count=`cat $inventory|wc -l`


for local_file_val in $file_listdo
        aws_folder=$2
        aws_file_name=`echo $local_file_val| rev| cut -d '/' -f1 | rev`
        aws_filepath="/${bucket}/$aws_folder/$aws_file_name"

        # metadata
        contentType="application/x-compressed-tar"
        dateValue=`date -R`
        signature_string="PUT\n\n${contentType}\n${dateValue}\n${aws_filepath}"
        signature_hash=`echo -en ${signature_string} | openssl sha1 -hmac ${s3_secret_key} -binary | base64`


        curl -X PUT -T "$local_file_val" \
    -H "Host: ${bucket}.s3.amazonaws.com" \
    -H "Date: ${dateValue}" \
    -H "Content-Type: ${contentType}" \
    -H "Authorization: AWS ${s3_access_key}:${signature_hash}" \
        https://${bucket}.s3.amazonaws.com/$aws_folder/$aws_file_name

    if [ $? -gt 0 ]; then
            echo "`date` Upload Failed  $local_file_val to $bucket" >> $logme
    else
            echo "`date` Upload Success $local_file_val to $bucket" >> $logme
            count=$((count + 1))
            printf "\rCopy Status -  $count/$total_file_count - Completed "

            sleep 1
            sed -i "/\/$aws_file_name/d" $inventory
    fi

done;

Feel free to comment.

Read more ...

Linux - Count no of files in a folder by day.

 


One Liner to count the number of files in a directory by date.

We often got this requirement where we have to deal with file counts, we have a huge list of files within a folder and we want to count the number of files created by date.

One Liner Linux CLI command

# find . -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c

 
Output for above command will look something like below.

1 2019-07-03 1 2019-08-08 6 2019-08-13 1 2019-08-15 1 2019-09-10 2 2019-09-11 1 2019-09-23 1 2019-10-22 1 2019-10-25 1 2019-10-29 1 2019-12-05 1 2020-03-04 2 2020-03-30 1 2020-04-07 11 2020-04-08 2 2020-04-09 1 2020-04-21 1 2020-04-26 2 2020-04-30 430 2020-05-06 1 2020-05-20 4 2020-05-26 951 2020-07-01 434 2020-07-02 1 2020-07-05 2 2020-07-06 100 2020-07-15 1 2020-07-28 6 2020-07-29 1 2020-08-01 2 2020-09-03


Let's break out the command and understand one by one highlighted in pale Yellow.

find . -type f

# find . -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c

Find . -type f 

Find command will fetch only the files ( -type f ) within present directory ( . )


-printf '%TY-%Tm-%Td\n'

# find . -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c

-printf '%TY-%Tm-%Td\n' will prints the modification time of files in e.g. 2020-04-26 format

sort | uniq -c
# find . -type f -printf '%TY-%Tm-%Td\n' | sort | uniq -c

sort : It will sorts the output 
uniq -c : It will count the sorted output by date.


Feel free to use it,  thank me later ;)

Read more ...

Unix/Linux Shell Scripting : How to search using AWK




AWK


Every unix/linux guy knows awk as a powerful tool, while writing a shell script, so today we will know 
  • How AWK can be used to search string from a file and return desired value as output.
  • How AWK can be used to search for a specific pattern
  • How can we use AWK to print based upon line number. 

We will start with our file, here is our file named demo.txt and it's content

cat demo.txt

FName|LName|Age|City|Country
Jill|Smith|50|NewYork|USA
Emi|Jackson|94|London|Britain
Raj|Dhinga|35|Delhi|India
Yan|Yun|21|Bejing|China
Yusuf|Khan|44|Mulheim|Germany
Will|Smith|40|NewYork|USA
Shail|Raj|21|Delhi|India
Vikram|Rajnand|34|Pune|India
HansRaj|Kedia|18|Mumbai|India
Devraj|Shukla|55|Dhanbad|India

AWK Basic Syntax :

  # awk options 'selection criteria { actions }' inputFile



How to use AWK with delimiter.

So we will start by printing the first field that is Fname and we will know, how we will separate fields when we have common delimiter.
Our file demo.txt has | as delimiter, so use the below one liner to separate fields.

  # awk -F '|' '{print $1}' demo.txt


-F followed by delimiter is used to process our requirement.

output
FName
Jill
Emi
Raj
Yan
Yusuf
Will
Shail
Vikram
HansRaj
Devraj
How to Use AWK to search and match for a string and print the entire field.

In our example file ( demo.txt), we will try to find a string "Raj" that can be part of the entire file, in case it founds the string it will print the entire line that contain the field with value "Raj"

  # awk -F "|" '/Raj/' demo.txt

-F followed by delimiter(|) and search string ( Raj ) placed within inverted comma and two backward slashes is used to process our requirement.

output
Raj|Dhinga|35|Delhi|India
Shail|Raj|21|Delhi|India
Vikram|Rajnand|34|Pune|India
HansRaj|Kedia|18|Mumbai|India
Output Analysis:

Field doesn't matter :
it's matching the word "Raj" irrespective of field,  thus printing the value of the entire line wherever it matches the search criteria.

Sub-Strings are also True matches: It doesn't matters if search string is a part of any sub-string.
Our input file has the below line that proves the statement.
Vikram|Rajnand|34|Pune|India
HansRaj|Kedia|18|Mumbai|India
Strict Matching : It strictly differentiate between upper case and lower case, our demo.txt file contains "raj" also as a part of substring but it ignores it as we have passed "Raj"
Devraj|Shukla|55|Dhanbad|India

How to Use AWK to search and match for a string and print only selected fields as an output.

So from our input file, we will match the same string "Raj" and try to print it's selected fields that is Fname($1), Age($3) and City($4)

  # awk -F "|" '/Raj/ {print $1, $3, $4}' demo.txt

-F followed by search string and  print statement with comma for space to create space between fields.

 
output
Raj 35 Delhi
Shail 21 Delhi
Vikram 34 Pune
HansRaj 18 Mumbai
How to Use AWK to search and match for a string and print only selected fields as an output with Line numbers.

So for all above search string matched lines, along with the output in order to print matched line numbers we can use NR combined with print statement, here is the one liner.

  # awk -F "|" '/Raj/ {print NR, $1, $3, $4}' demo.txt

-F followed by search string and  print statement starting with NR



output
4 Raj 35 Delhi
8 Shail 21 Delhi
9 Vikram 34 Pune
10 HansRaj 18 Mumbai

AWK Search pattern to ignore difference between upper and lower case.

From our input file, we want to add lines that contain "Raj" and "raj" both


  # awk -F "|" '/[Rr]aj/' demo.txt

-F followed by pattern [Rr] to add both the values.

output
Raj|Dhinga|35|Delhi|India
Shail|Raj|21|Delhi|India
Vikram|Rajnand|34|Pune|India
HansRaj|Kedia|18|Mumbai|India
Devraj|Shukla|55|Dhanbad|India

AWK to print by line number only.


From our input file,if we just want to print only 3rd line only, below is the one liner and it's output.

 # awk -F "|" 'NR==3'  demo.txt

-F followed by delimiter and "NR==3" where 3 is the line number,

output
Emi|Jackson|94|London|Britain
AWK to print between two line number.


From our input file,if we just want to print between line number 2 and 5, below is the one liner and it's output.

 # awk -F "|" ' NR==2, NR==5 {print NR,  $1, $3, $4}' demo.txt

-F followed by delimiter and "NR==2" a comma(,) and "NR==5"

output
2 Jill 50 NewYork
3 Emi 94 London
4 Raj 35 Delhi
5 Yan 21 Bejing


AWK to print between two line number and it's output value to a file.


From our input file,if we just want to print between line number 2 and 5, below is the one liner and it's output.

 # awk -F "|" ' NR==2, NR==5 {print NR,  $1, $3, $4}' demo.txt >> /tmp/newfile.txt




Read more ...

Linux Find Commands with examples.



Linux Find Commands Cheat sheet.

Find Files Using Name in Current Directory.
Lets assume we are currently under our /home directory.
  # find . -name myfile.txt
     /home/myfile.txt


Find Files Using Name and Ignoring Case ( Ignore upper & lower case )


  # find . -iname myfile.txt
     /home/myfile.txt
     /home/MYFILE.txt

Find Files under any specified Directory.


  # find . -iname myfile.txt

     /home/myfile.txt

     /home/MYFILE.txt


Find Files Using Name and Ignoring Case ( Ignore upper & lower case )

      #  find . -iname myfile.txt
    
         /home/myfile.txt
    
         /home/MYFILE.txt


    Find files  based on extention ( .php .txt .csv .sh )


      #  find . -type f -name "*.php"
    
         /home/myfile.php
    
         /home/index.php
    
    
    
     #  find . -type f -name "*.csv"
    
         /home/abc.csv
    
         /home/newfile.csv
    
    
    
     #  find . -type f -name "*.sh"
    
         /home/myscript.sh
    
         /home/new.sh
    
    
    
    
    


    Find Directories 


      #  find . -type d -name  mydirectory
    
    
        /home/mydirectory


    Find files with 777 Permission


      #  find /home   -type f -perm 0777 -print
    
          /home/abc.txt

    Find files without  755 Permission


       #  find /home  -type f ! -perm 755
    
           /home/myfile.txt
    
           /home/MYFILE.txt


    Find  all files Based on User
    We will find all files placed within /home directory having ownership of user jackuna
      #  find /home -user jackuna
    
          /home/myfile.txt


    Find  all files based on specific Group
    We will find all files placed within /home directory having group of user sysadmins
      #  find /home -group sysadmins
    
          /home/admin.sh


    Find  specific file type for a user
    We will find all files with .txt extension for user jackuna under /home directory
      #  find /home -user jackuna -iname "*.txt"
    
         /home/myfile.txt


    Find all empty files ( no content )
    We will find all empty/blank files  under /tmp directory.
       #  find /tmp -type f -empty


    Find all empty directories ( no content )
    We will find all empty/blank directories  under /tmp directory.
       #  find /tmp -type d -empty


    Find all hidden files
    We will find all hidden files under /tmp directory.
       #  find /tmp -type f -name ".*"


    Find  and remove a single file
    We will find file named as  myfile.txt  under /home directory and remove it permanently 
      #  find /home  -type f -name "myfile.txt" -exec rm -f {} \;


    Find  and remove a multi[ple file
    We will find all files with .sh and .mp3 extension under /home and delete it permanently 
      #  find /home -type f -name "*.sh" -exec rm -f {} \;
     
      #  find  /home  -type f -name "*.mp3" -exec rm -f {} \;


    Find files that are older then n number of days 
    Below find command will find all files that are older then 20 days under /tmp directory
      #  find  /tmp -mtime +20 -print
    


    Find files that are accessed then n number of days before
    Below find command will find all files that are accessed  20 days before under /tmp directory
      #  find  /tmp -atime +20 -print


    Find files that are changed within last hour
    Below find command will find all files that are changed within last 60 min under /tmp directory
      #  find /tmp -cmin -60


    Find modified files in last 60 minutes
    Below find command will find all files that are modified within last 60 min under /tmp directory
      #  find /tmp -mmin -60


    Find accessed files in last 60 minutes
    Below find command will find all files that are accessed within last 60 min under /tmp directory
      #  find /tmp -amin -60

    
    
    Read more ...
    Designed By Jackuna