how to make the below output of the command pass not fail - regex

how to make the below output of the regex command pass not fail
grep -E '^[[:space:]]*-a[[:space:]]+always,exit[[:space:]]+-F[[:space:]]+arch=b32[[:space:]]+-S[[:space:]]+creat[[:space:]]+-S[[:space:]]+open[[:space:]]+-S[[:space:]]+openat[[:space:]]+-S[[:space:]]+truncate[[:space:]]+-S[[:space:]]+ftruncate[[:space:]]+-F[[:space:]]+exit=-EACCES[[:space:]]+-F[[:space:]]+auid>=500[[:space:]]+-F[[:space:]]+auid!=4294967295[[:space:]]+-k[[:space:]]+access[[:space:]]*$' /etc/audit/rules.d/*.rules | /usr/bin/awk '{print} END {if (NR != 0) print "pass" ; else print "fail"}'
I tried the below and still fail
echo -e "-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access\n-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access\n-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access\n-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access" > /etc/audit/rules.d/access.rules

Related

VIM: match number following PATTERN, replace with number + 1

I have a set of lines that look like:
$AERDIR/aergen.sh -n control -s 2100 -e 2120 -m 3 -a -x -z 144 -p -g
$AERDIR/aergen.sh -n Cl26E10 -s 2100 -e 2120 -m 3 -a -x -c 2.6E-10 -z 145 -p -g
$AERDIR/aergen.sh -n Br26E12 -s 2100 -e 2120 -m 3 -a -x -b 2.6E-12 -z 146 -p -g
$AERDIR/aergen.sh -n I26E13 -s 2100 -e 2120 -m 3 -a -x -i 2.6E-13 -z 147 -p -g
I would like to match the three digit number after -z and replace it with that number +1, so
$AERDIR/aergen.sh -n control -s 2100 -e 2120 -m 3 -a -x -z 145 -p -g
$AERDIR/aergen.sh -n Cl26E10 -s 2100 -e 2120 -m 3 -a -x -c 2.6E-10 -z 146 -p -g
$AERDIR/aergen.sh -n Br26E12 -s 2100 -e 2120 -m 3 -a -x -b 2.6E-12 -z 147 -p -g
$AERDIR/aergen.sh -n I26E13 -s 2100 -e 2120 -m 3 -a -x -i 2.6E-13 -z 148 -p -g
I've been playing around with submatch parameters and such, but have only managed to increment the first appearance of numbers in each line. How would I formulate a command to do this, say from line 203,$ ?
This is a job for submatch:
%s/-z \zs\d\+/\=submatch(0)+1/
The pattern -z \zs\d\+ matches one or more digits \d\+ preceeded by -z. Then \=submatch(0)+1 adds one to the matched number.

Sed replace a string in the first line of a paragraph

I am trying to automate the periodic detection and elimination of files, using fdupes. I got this beautiful script:
# from here:
# https://www.techrepublic.com/blog/linux-and-open-source/how-to-remove-duplicate-files-without-wasting-time/
OUTF=rem-duplicates_2019-01.sh;
echo "#! /bin/sh" > $OUTF;
find "$#" -type f -printf "%s\n" | sort -n | uniq -d |
xargs -I## -n1 find "$#" -type f -size ##c -exec md5sum {} \; |
sort --key=1,32 | uniq -w 32 -d --all-repeated=separate |
sed -r 's/^[0-9a-f]*( )*//;s/([^a-zA-Z0-9./_-])/\\\1/g;s/(.+)/#rm \1/;' >> $OUTF;
chmod a+x $OUTF; ls -l $OUTF
This produces a file with this structure:
#! /bin/sh
#rm ./directory_a/file_a
#rm ./directory_b/file_identical_to_a
#rm ./directory_a/file_b
#rm ./directory_b/file_identical_to_b
#rm ./directory_c/another_file_identical_to_b
#rm ./directory_a/file_c
#rm ./directory_b/file_identical_to_c
#rm ./directory_c/another_file_identical_to_c
#rm ./directory_d/yet_another_file_identical_to_c
I want to remove the # tag from the first line of each paragraph to get
rm ./directory_a/file_c
#rm ./directory_b/file_identical_to_c
#rm ./directory_c/another_file_identical_to_c
#rm ./directory_d/yet_another_file_identical_to_c
I have been trying to modify the next-to-last line, with variations of things like this:
sed -r 's/^[0-9a-f]*( )*//;s/([^a-zA-Z0-9./_-])/\\\1/g;s/(.+)/#rm \1/;s/\n\n#rm/\n\nrm/;' >> $OUTF;
But cannot manage SED to recognize the (\n\n) or any other pointer I can think of to the beginning of the paragraph. What am I doing wrong?
Edit: I am unable to edit the comment, so here is the final script:
TEMPF=temp.txt;
OUTF=rem-duplic_2019-01.sh
echo "#! /bin/sh" > $TEMPF;
find "$#" -type f -printf "%s\n" | sort -n | uniq -d |
xargs -I## -n1 find "$#" -type f -size ##c -exec md5sum {} \; |
sort --key=1,32 | uniq -w 32 -d --all-repeated=separate |
sed -r 's/^[0-9a-f]*( )*//;s/([^a-zA-Z0-9./_-])/\\\1/g;s/(.+)/#rm \1/' >> $TEMPF;
awk -v a=2 '/^$/{a=2}!--a{sub(/#/,"")}1' $TEMPF > $OUTF
chmod a+x $OUTF; ls -l $OUTF
rm $TEMPF
Use awk instead:
awk '/^$/{a=1} !a--{sub(/#/,"")} 1' a=1 file
/^$/ { a = 1 } means set a to 1 if current line is a blank one,
!a-- is a shorthand for a-- == 0, following action ({ sub(/#/, "") }) removes the first # from current line,
1 means print all lines,
a=1 is required to remove # from the line after shebang (i.e 2nd line).
With sed:
sed "1n;/^#/,/^$/{ s///;}" file
You can use this too:
sed '/^$\|^#!/{N;s/#r/r/}' input.txt
feel free to add the in-place opt if you want
This might work for you (GNU sed):
sed '/^#!\|^\s*$/{n;s/.//}' file
If the current line is a shebang or an empty line, print it and remove the first character of the next line.
Just use Perl with paragraph mode
perl -00 -pe ' s/^#// '
With inputs
$ cat yozzarian.txt
#! /bin/sh
#rm ./directory_a/file_a
#rm ./directory_b/file_identical_to_a
#rm ./directory_a/file_b
#rm ./directory_b/file_identical_to_b
#rm ./directory_c/another_file_identical_to_b
#rm ./directory_a/file_c
#rm ./directory_b/file_identical_to_c
#rm ./directory_c/another_file_identical_to_c
#rm ./directory_d/yet_another_file_identical_to_c
$ perl -00 -pe ' s/^#// ' yozzarian.txt
! /bin/sh
#rm ./directory_a/file_a
#rm ./directory_b/file_identical_to_a
rm ./directory_a/file_b
#rm ./directory_b/file_identical_to_b
#rm ./directory_c/another_file_identical_to_b
rm ./directory_a/file_c
#rm ./directory_b/file_identical_to_c
#rm ./directory_c/another_file_identical_to_c
#rm ./directory_d/yet_another_file_identical_to_c
$

How to capture "*" as argument to bash function and use in a comparison

I want to have bash run rm -i * if I type rm * but otherwise run regular rm. Importantly, I don't want to run rm -i every time I use a wildcard such as rm part*. Here is as far as I could come up with:
rm ()
{
if [ "$1" == "*" ]; then
rm -i *
else
rm $1
fi
}
But I know this will fail. I know that the comparison I want is to ^*$, but I don't know how to implement it.
It's literally impossible to know if your command was called with a wildcard without the cooperation of your shell.
When you invoke rm * (like any other command), the * is replaced with a list of filenames before invocation. Thus, when inside the command, the information that it was given a wildcard no longer exists: $1, $2, etc. have been replaced with a list of names that the wildcard expanded to.
That said, since we're a shell function, the cooperation of our shell is actually available:
rm() {
local cmd
read -r _ cmd < <(HISTTIMEFORMAT=''; history 1)
if [[ $cmd = "rm *" ]]; then
command rm -i "$#"
else
command rm "$#"
fi
}
How does this work?
history 1 returns the most recent command in the shell's history (preceded by a number).
read -r _ cmd reads that number into the variable _, and the rest of the command line into the variable cmd
[[ $cmd = "rm *" ]] compares the command against that precise string
command rm ... runs the external rm command, avoiding recursion back to our function again.
Since you can't know if there is a wildcard, why not check the number of arguments?
For example:
#!/bin/bash
rm () {
if [ "$#" -gt 1 ]; then
echo command rm -i "$#"
else
echo command rm "$#"
fi
}
rm a b c
rm a

How to find specific files in folders and do an operation in case they exist

I am having some difficulty doing a basic script in sh shell.
What I want to do is simple though:
I want to do a sh script (can also be csh) that looks through a number of folders and for each folder that contains the files I am interested in, it should do a specific operation of pasting the corresponding filename into a sh script with rdseed commands.
The script I wrote in sh shell and doesn't work is:
for dir in EV*
do
echo $dir
cd $dir
if [ -f GEFLE* = true ];
then
set dataless = gur_ini_dataless.seed
for file GEFLE*
do
echo "rdseed -d -o 2 -f "$file " -g " $dataless >> runmseed2ahGEFLE.sh
done
else
echo "File does not exists"
fi
sleep 0.5
cd ..
done
Does anyone know a solution?
Please try this... I'm adding some comments to the lines...
#!/bin/sh
for dir in EV*
do
echo $dir
cd $dir
if [ -f GEFLE* ] # true if at least one FILE named "GEFLE*" exists
then
dataless=gur_ini_dataless.seed # no `set`, no spaces
for file in GEFLE* # will match all FILES/DIRS/... that start with "GEFLE"
do
echo "rdseed -d -o 2 -f $file -g $dataless" >> runmseed2ahGEFLE.sh # vars are substituted in double quoted strings
done
else
echo "File does not exists"
fi
cd ..
done
Please note this will only look one level deep into the directories. If you need some resursion you should better use something like
for dir in `find . -type d -name 'EV*'`; do
# ...
done
The way I had put this is:
for f in `find EV* -name GEFLE* -type f`; do
echo "rdseed -d -o 2 -f ./$f -g gur_ini_dataless.seed >> ./`dirname $f`/runmseed2ahGEFLE.sh"
done

Using SED to replace a pattern causes extra characters to appear

I have a file and want to replace a pattern with another string.
#PBS -N bench1-M1-plt2-size15
#PBS -o /home/results/bench1-M1-plt2-size15.out
./run -d ./results/ --config=bench1-M1-plt2-size15.conf \
--results=bench1-M1-plt2-size15.res config/myConfig.txt -F 2000000
I use this command
sed 's/M1-[^-]*-[^-]/M1-plt32-size10/g' filename
However the output file looks like this:
#PBS -N M1-plt32-size100
#PBS -o /home/mahmood/gem5/results/M1-plt32-size100.out
./run -d ./results/ --config=bench1-M1-plt32-size100.conf \
--results=bench1-M1-plt32-size100.res config/myConfig.txt -F 2000000
Please note an extra '0' character after "size10". As you can see, in the SED command, size is set to 10, however the output file is "size100"
What is the problem and how can I fix that?
Your regex is not correct. You have [^-] which will match only 1 non-hyphen character. I believe this is what you intended:
sed 's/M1-[^-]*-[^\.]*/M1-plt32-size10/' filename
OUTPUT:
#PBS -N bench1-M1-plt32-size10
#PBS -o /home/results/bench1-M1-plt32-size10.out
./run -d ./results/ --config=bench1-M1-plt32-size10.conf \
--results=bench1-M1-plt32-size10.res config/myConfig.txt -F 2000000