Need a solution for grep command for .gz files - linux

I have file names starts with RACHEL_20180814_092356.csv.gz
and need to grep in format like RACHEL_20180814*.gz nd unzip it, but am unable too. Here is sample code I have been working on.need to also insert a date parameter, which changes with each day. tried using zgrep but I am out of luck! Any help please
Process GMRA file
echo "Starting file get for Rachel.gz files"
for SUBDIR in prices; do
set -A getlist `/bin/ls ${ENV_DIR_SCR}/bat/prices`
if [ ! -z ${getlist[0]} ]; then
for FILENAME in ${getlist[*]}; do
echo "Found File ${ENV_DIR_SCR}/bat/prices/${FILENAME}"
if [ `echo $FILENAME | grep "RACHEL*.gz"` ]; then
$FILENAME = gunzip $FILENAME
GETFILES="$GETFILES ${FILENAME}"
break
fi
done
fi
done echo "Completed file_get for RACHEL.gz files"

Related

How to extract only file name return from diff command?

I am trying to prepare a bash script for sync 2 directories. But I am not able to file name return from diff. everytime it converts to array.
Here is my code :
#!/bin/bash
DIRS1=`diff -r /opt/lampp/htdocs/scripts/dev/ /opt/lampp/htdocs/scripts/www/ `
for DIR in $DIRS1
do
echo $DIR
done
And if I run this script I get out put something like this :
Only
in
/opt/lampp/htdocs/scripts/www/:
file1
diff
-r
"/opt/lampp/htdocs/scripts/dev/File
1.txt"
"/opt/lampp/htdocs/scripts/www/File
1.txt"
0a1
>
sa
das
Only
in
/opt/lampp/htdocs/scripts/www/:
File
1.txt~
Only
in
/opt/lampp/htdocs/scripts/www/:
file
2
-
second
Actually I just want to file name where I find the diffrence so I can take perticular action either copy/delete.
Thanks
I don't think diff produces output which can be parsed easily for your purposes. It's possible to solve your problem by iterating over the files in the two directories and running diff on them, using the return value from diff instead (and throwing the diff output away).
The code to do this is a bit long, but here it is:
DIR1=./one # set as required
DIR2=./two # set as required
# Process any files in $DIR1 only, or in both $DIR1 and $DIR2
find $DIR1 -type f -print0 | while read -d $'\0' -r file1; do
relative_path=${file1#${DIR1}/};
file2="$DIR2/$relative_path"
if [[ ! -f "$file2" ]]; then
echo "'$relative_path' in '$DIR1' only"
# Do more stuff here
elif diff -q "$file1" "$file2" >/dev/null; then
echo "'$relative_path' same in '$DIR1' and '$DIR2'"
# Do more stuff here
else
echo "'$relative_path' different between '$DIR1' and '$DIR2'"
# Do more stuff here
fi
done
# Process files in $DIR2 only
find $DIR2 -type f -print0 | while read -d $'\0' -r file2; do
relative_path=${file2#${DIR2}/};
file1="$DIR1/$relative_path"
if [[ ! -f "$file2" ]]; then
echo "'$relative_path' in '$DIR2 only'"
# Do more stuff here
fi
done
This code leverages some tricks to safely handle files which contain spaces, which would be very difficult to get working by parsing diff output. You can find more details on that topic here.
Of course this doesn't do anything regarding files which have the same contents but different names or are located in different directories.
I tested by populating two test directories as follows:
echo "dir one only" > "$DIR1/dir one only.txt"
echo "dir two only" > "$DIR2/dir two only.txt"
echo "in both, same" > $DIR1/"in both, same.txt"
echo "in both, same" > $DIR2/"in both, same.txt"
echo "in both, and different" > $DIR1/"in both, different.txt"
echo "in both, but different" > $DIR2/"in both, different.txt"
My output was:
'dir one only.txt' in './one' only
'in both, different.txt' different between './one' and './two'
'in both, same.txt' same in './one' and './two'
Use -q flag and avoid the for loop:
diff -rq /opt/lampp/htdocs/scripts/dev/ /opt/lampp/htdocs/scripts/www/
If you only want the files that differs:
diff -rq /opt/lampp/htdocs/scripts/dev/ /opt/lampp/htdocs/scripts/www/ |grep -Po '(?<=Files )\w+'|while read file; do
echo $file
done
-q --brief
Output only whether files differ.
But defitnitely you should check rsync: http://linux.die.net/man/1/rsync

Check that two file exists in UNIX Directory

Good Morning,
I am trying to write a korn shell script to look inside a directory that contains loads of files and check that each file also exists with .orig on the end.
For example if a file inside the directory is called 'mercury_1' there must also be a file called 'mercury_1.orig'
If there isn't, it needs to move the mercury_1 file to another location. However if the .orig file exists do nothing and move onto the next file.
I am sure it is really simple but I am not that experienced in writing Linux scripts and help would be greatly appreciated!!
Here's a small ksh snippet to check if a file exists in the current directory
fname=mercury_1
if [ -f $fname ]
then
echo "file exists"
else
echo "file doesn't exit"
fi
Edit:
The updated script that does the said functionality
#/usr/bin/ksh
if [ ! $# -eq 1 ]
then
echo "provide dir"
exit
fi
dir=$1
cd $dir
#process file names not ending with orig
for fname in `ls | grep -v ".orig$"`
do
echo processing file $fname
if [ -d $fname ] #skip directory
then
continue
fi
if [ -f "$fname.orig" ] #if equiv. orig file present
then
echo "file exist"
continue
else
echo "moving"
mv $fname /tmp
fi
done
Hope its of help!
You can use the below script
script.sh :
#!/bin/sh
if [ ! $# -eq 2 ]; then
echo "error";
exit;
fi
for File in $1/*
do
Tfile=${File%%.*}
if [ ! -f $Tfile.orig ]; then
echo "$File"
mv $File $2/
fi
done
Usage:
./script.sh <search directory> <destination dir if file not present>
Here, for each file with extension stripped check if "*.orig" is present, if not then move file to different directory, else do nothing.
Extension is stripped because you don't want to repeat the same steps for *.orig files.
I tested this on OSX (basically mv should not differ to much from linux). My test directory is zbar and destination is /tmp directory
#!/bin/bash
FILES=zbar
cd $FILES
array=$(ls -p |grep -v "/") # we search for file without extension so put them in array and ignore directory
echo $array
for f in $array #loop in array and find .orig file
do
#echo $f
if [ -e "$f.orig" ]
then
echo "found $f.orig"
else
mv -f "$f" "/tmp"
fi
done

Md5 Hash to identify and archive images

This is my first ever bash script and I am trying to iron out all of the creases and make the script run nicely. The script is to archive all of the specified .jpg files that it finds in multiple directories on a HDD/Flash drive. There are files with the same name but different content so I have used an Md5 sum to hash them.
I am getting the directory does not exist error in Geany but it runs fine from command bar missing out two of the images. I have tried everything I can think of to fix it. Is it messy code that is doing this?
#!/bin/sh
if [ ! -d "$1" ]; then
echo Directory "$1" cannot be found. Please try again.
exit
fi
if [ $# -eq 1 ]; then
echo "usage: Phar image_path archive_path"
exit
fi
if [ -d "$2" ]; then
echo "archive exists"
else
echo "the directory 'archive' does't exist. Creating directory 'archive'."
mkdir -p ~/archive
fi
find $1 -iname "IMG_[0-9][0-9][0-9][0-9].JPG" | cat > list.txt
[ -f ~/my-documents/md5.txt ] && rm md5.txt || break
while read line;
do md5sum $line | xargs >> md5.txt
done < list.txt
sort -k 1,1 -u md5.txt | cat > uniquemd5.txt
cut -d " " -f 2- uniquemd5.txt > uniquelist.txt
sort uniquelist.txt -r -o uniquelist.txt
for line in $(cat uniquelist.txt)
do
file=$(basename $line) path="$2/file"
if [ ! -f $path ];
then
cp $line $2
else
cp $line $path.JPG
fi
done
You haven't guarded against spaces in the folder and file names everywhere.
For instance:
cp $line $2
should be:
cp "$line" "$2"
You should start by eliminating these spaces as a source to your error by evaluating each variable you are referencing and adding ""'s.
If you still get the error please provide us with the arguments used and which directory that does not exist.

Editing every file in a directory after opening it bash

Looking around I didn't see exactly what I was looking for. Some similar stuff, but for some reason what I tried so far hasn't worked.
My main goals:
run script in my current directory
open the picture to see what it is
rename the picture i just viewed
repeat the process without running the script again
These were the sources I attempted to follow:
Bash Shell Loop Over Set of Files
Bash loop through directory and rename every file
How to do something to every file in a directory using bash?
==================================================================================
echo "Rename pictures. Path"
read path
for f in $path
do
eog $path
echo "new name"
read newname
mv $path $newname
cat $f
done
You should pass the script an argument rather than trying to make it interactive. You also have numerous quoting problems. Try something like this instead (untested):
#!/usr/bin/env bash
moveFile() {
local newName=
until [[ $newName ]]; do
printf '%s ' 'new name:'
read -er newName # -e implies Bash with readline
echo
done
mv -i "$1" "${1%/*}/${newName}"
}
if [[ ! -d $1 ]]; then
echo 'Must specify a path' >&2
exit 1
fi
for f in "$1"/*; do
eog "$f"
moveFile "$f"
done
You might want to try something like this:
for f in $*; do
eog $f
echo "new name:"
read newname
mv $f $newname
done
If you name the script, say, rename.sh, you can call
./rename.sh *gif
to review all files with extention 'gif'.
Using find command allows you to search for image files in the specified directory recursively.
echo -n "Rename pictures. Input image directory: "
read path
for f in `find $path -type f`
do
eog $f
echo -n "Enter new name: "
read newname
mv $f $newname
echo "Renamed $f to $newname."
done

printing folder names in bash

This piece of bash code, shows no folder name while there exists many folders.
#!/bin/bash
for file in .; do
if [ -d $file ]; then
echo $file
fi
done
the output is only .
Can you explain why?
it reads . as an array of size one and prints it for you. use something like this instead:
for file in `ls`; do
if [ -d $file ]; then
echo $file
fi
done

Resources