Not able to read file content with sed command - unix

I am trying to read the below file line by line to perform the below operations
Extract the name of the file/directory alone and assign it one variable,
Extract the permission available in the line and add comma between the permission. Then assign it to another variable,
At last applying setfacl logic as shown in the output section.
File
# file: /disk1/script_1/ user::rwx group::r-x group:service:r-x mask::r-x other::r-x
# file: /disk1/script_1//hello.txt user::rw- group::r-- other::r--
# file: /disk1/script_1//bkp_10.txt user::rwx group::r-x other::r-x
Code
input="bkp_23.txt"
while IFS= read -r line;
do
echo $line
file_name=`sed -e 's/# file:\(.*\)/\1/g' "$line" | awk '{print $1}'`
echo $file_name
file_perm=`sed -e 's/# file:\(.*\)/\1/g' "$line" | awk '{$1=""}{print}' | tr ' ' ',' | awk
'{sub(",","")}1'`
echo $file_perm
echo "setfacl -m "$file_perm" "$file_name" executing"
done <"$input"
Output
setfacl -m user::rwx,group::r-x,group:service:r-x,mask::r-x,other::r-x /disk1/script_1/
setfacl -m user::rw-,group::r--,other::r-- /disk1/script_1//hello.txt
setfacl -m user::rwx,group::r-x,other::r-x /disk1/script_1//bkp_10.txt
Error
sed: can't read # file: /disk1/script_1/ user::rwx group::r-x group:service:r-x mask::r-x other::r-x: No such file or directory

$ cat input
# file: /disk1/script_1/ user::rwx group::r-x group:service:r-x mask::r-x other::r-x
# file: /disk1/script_1//hello.txt user::rw- group::r-- other::r--
# file: /disk1/script_1//bkp_10.txt user::rwx group::r-x other::r-x
$ while read _ _ path perms; do perms="$(echo "$perms" | tr -s ' ' ,)"; echo path="$path", perms="$perms"; done < input
path=/disk1/script_1/, perms=user::rwx,group::r-x,group:service:r-x,mask::r-x,other::r-x
path=/disk1/script_1//hello.txt, perms=user::rw-,group::r--,other::r--
path=/disk1/script_1//bkp_10.txt, perms=user::rwx,group::r-x,other::r-x

Try to echo the line content along with sed logic like this
file_name=$(echo "$line" | sed 's/# file:\(.*\)/\1/g' | awk '{print $1}')
file_perm=$(echo "$line" | sed -e 's/# file:\(.*\)/\1/g' | awk '{$1=""}{print}' | tr ' ' ',' | awk '{sub(",","")}1')

Related

SED command use for writing back to the same file

I have the below code which adds Logger.info line after every function definition which I need to run on a python script which is the requirement.
The only question is this has to be written back to the same file so the new file has all these looger.info statements below each function definition.
e.g. the file abc.py has currently below code :
def run_func(sql_query):
return run_func(sql_query)
and the code below should create the same abc.py file but with all the logger.info added to this new file
def run_func(sql_query):
LOGGER.info (''MIPY_INVOKING run_func function for abc file in directory'
return run_func(sql_query)
I am not able to write the sed in this file to the new file (with same file name) so that the original file gets replaced by same file name and so that I have all the logger.info statements in there.
for i in $(find * -name '*.py');
do echo "#############################################" | tee -a auto_logger.log
echo "File Name : $i" | tee -a auto_logger.log
echo "Listing the python files in the current script $i" | tee -a auto_logger.log
for j in $(grep "def " $i | awk '{print $2}' | awk -F"(" '{print $1}');
do
echo "Function name : $j" | tee -a auto_logger.log
echo "Writing the INVOKING statements for $j function definition" | tee -a auto_logger.log
grep "def " $i |sed '/):/w a LOGGER.info (''INVOKING1 '"$j"' function for '"$i"' file in sam_utilities'')'
if [ $? -ne 0 ] ; then
echo " Auto Logger for $i filename - Not Executed Successfully" | tee -a auto_logger.log
else
echo "Auto Logger for $i filename - Executed Successfully" | tee -a auto_logger.log
fi
done
done

While loop skips the first line in output

I'm using the below command in Terminal on a Mac to read a file of email addresses and convert them to a MD5 hash.
tr -d " " < em.txt | tr '[:upper:]' '[:lower:]' | while read line; do
(echo -n $line | md5); done | awk '{print $1}' > hashes1.txt
This produces a file of hashes that are 1 row shorter than the original input file. But I can't figure out why.
This code does a few things, below.
Converts an email address to all lower case
Converts the email address to a MD5 Hash
Outputs a list of new email addresses to a hashes1.txt file
Thanks in advance!
Your tr command is wrong : it should be :
tr -d " " < em.txt |
tr '[[:upper:]]' '[[:lower:]]' |
while IFS= read -r line; do
echo -n "$line" | md5 | awk '{print $1}' >> hashes1.txt
done
or
while IFS= read -r line; do
echo -n "$line" | md5 | awk '{print $1}' >> hashes1.txt
done < <(tr -d " " < em.txt | tr '[[:upper:]]' '[[:lower:]]')
Changed the file feeding place too.
And ensure your file don't have strange characters with
od -c file
if yes, install dos2unix, then :
dos2unix file
or using perl :
perl -i -pe 's/\r//g' file

Unix script to recursively search a directory and sub directories to grep and print content between 2 patterns in file

I have some files in a directory and sub directories. I need to search all the files and print the file name and the content between 2 matching patterns in the file.
For e.g. lets say my file looks like below.
File1.txt:
Pattern1
ABCDEFGHI
Pattern2
dafoaf
fafaf
dfadf
afadf
File2.txt
Pattern1
XXXXXXXXX
Pattern2
kdfaf
adfdaf
fdafad
I need to get following output
File1.txt:
ABCDEGHI
File2.txt:
XXXXXXXX
and so on for all the files under directory and sub directories separated by new line.
This might work for you:
find . \
-type f \
-exec awk 'BEGING {print FILENAME ":"} /Pattern1/ { p=1 ; next } /Pattern2/ {p=0} p==1 {print $0} END {print ""}' \{\} \;
Note, this prints the FILENAME, even if Pattern1 was not found!
This will work for you :
Create this shell script as my_grep.sh
#!/bin/sh
grep -nH "Pattern" $1 >>temp
if [ `grep -c $1 temp` -eq 2 ]; then
limits=`grep $1 temp | cut -f2 -d:`
lower_limit=`echo $limits | cut -f1 -d" "`
upper_limit=`echo $limits | cut -f2 -d" "`
echo "$1:"
head -`expr $upper_limit - 1` $1 | tail -`expr $upper_limit - $lower_limit - 1`
fi
Use find command to search files and fire this schell script:
$ find ./test -type f -exec ./my_grep {} \;
./test/File1.txt:
ABCDEFGHI
./test/File2.txt:
XXXXXXXXX

Unix script to delete file if it contains single line

Consider I have a file abcde.txt which may contain one or more lines of text. I want a script that will DELETE the file if it contains single line.
Something like, if 'wc -l abscde.txt' = 1 then rm abscde.txt
My system : Solaris
Here's a simple bash script:
#!/bin/bash
LINECOUNT=`wc -l abscde.txt | cut -f1 -d' '`
if [[ $LINECOUNT == 1 ]]; then
rm -f abscde.txt
fi
delifsingleline () {
if [ $(cat $1 | wc -l) = "1" ]
then
echo "Deleting $1"
echo "rm $1"
fi
}
Lightly tested on zsh. Should work on bash as well.
This is (mostly) just a reformat of Ben's answer:
wc -l $PATH | grep '^1 ' > /dev/null && rm -f $PATH

Insert copyright message into multiple files

How would you insert a copyright message at the very top of every file?
#!/bin/bash
for file in *; do
echo "Copyright" > tempfile;
cat $file >> tempfile;
mv tempfile $file;
done
Recursive solution (finds all .txt files in all subdirectories):
#!/bin/bash
for file in $(find . -type f -name \*.txt); do
echo "Copyright" > copyright-file.txt;
echo "" >> copyright-file.txt;
cat $file >> copyright-file.txt;
mv copyright-file.txt $file;
done
Use caution; if spaces exist in file names you might get unexpected behaviour.
sed
echo "Copyright" > tempfile
sed -i.bak "1i $(<tempfile)" file*
Or shell
#!/bin/bash
shopt -s nullglob
for file in *; do
if [ -f "$file" ];then
echo "Copyright" > tempfile
cat "$file" >> tempfile;
mv tempfile "$file";
fi
done
to do it recursive, if you have bash 4.0
#!/bin/bash
shopt -s nullglob
shopt -s globstar
for file in /path/**
do
if [ -f "$file" ];then
echo "Copyright" > tempfile
cat "$file" >> tempfile;
mv tempfile "$file";
fi
done
or using find
find /path -type f | while read -r file
do
echo "Copyright" > tempfile
cat "$file" >> tempfile;
mv tempfile "$file";
done
You may use this simple script
#!/bin/bash
# Usage: script.sh file
cat copyright.tpl $1 > tmp
mv $1 $1.tmp # optional
mv tmp $1
File list may be managed via find utility
Working in Mac OSX:
#!/usr/bin/env bash
for f in `find . -iname "*.ts"`; do # just for *.ts files
echo -e "/*\n * My Company \n *\n * Copyright © 2018 MyCompany. All rights reserved.\n *\n *\n */" > tmpfile
cat $f >> tmpfile
mv tmpfile $f
done

Resources