Regex to extract just a portion of the base filename - bash

I'm pretty new to regex and I'm trying to get the portion of a base filename to reuse later in a variable. I'm running tests with echo in order to see the output but I haven't been able to get it to work how I expect. This is the piece of code I've come up with.
#!/bin/bash
search_dir=/var/FTP/DB
filter="[^_0-9.ra]"
for entry in "$search_dir"/*
do
echo $(basename $entry) #| grep -oP $filter
done
It successfully takes the part of the base filename I want but it's splitting each letter in a new line. Can someone help me get this straighten out?
EDIT:
File in /var/FTP/DB:
TEXT_04-20-20-15-55.zip
LEARN_03-22-19-00-01.rar
Desired output:
TEXT
LEARN

#!/bin/bash
search_dir=.
filter="_.*$";
for entry in "$search_dir"/*
do
echo $(basename $entry) | sed -e "s/$filter//"
done

Related

save each grepped line as a separate .txt file using bash

I have a file .txt with some informations, i need to grep the "Report:" line and save each line in a different .txt file!
it should result something like this in the end:
case1.txt
case2.txt
case3.txt
I tried to
cat cases.txt| grep Report: | while read Report; do echo $Report | > /home/kali/Desktop/allcases/case.txt done
but it didnt work and just created one file called case.txt containing the last grepped "Report:"
I dont know if i was very clear then i'll show this screenshot:
cases
I wanted to split all theses reports in a different .txt file for each report!
These case informations are from a game, so dont worry!
awk would be better suited than grep and a while loop. If acceptable, you can try;
awk '/^Report/{cnt++;close(report); report="case"cnt".txt"}/./{print > report}' file.txt
perl -ne '++$i && `printf "$_" > case$i.txt` if /Report:/' cases.txt
This is looping over cases.txt and shelling out printf "$_" > case$i.txt if the line matches /Report:/
Because it's perl there's some syntax and precedence tricks in here to make it terse and confusing.

Bash show charcaters if not in string

I am trying out bash, and I am trying to make a simple hangman game now.
Everything is working but I don't understand how to do one thing:
I am showing the user the word with guessed letters (so for example is the world is hello world, and the user guessed the 'l' I show them **ll* ***l* )
I store the letters that the user already tried in var guess
I do that with the following:
echo "${word//[^[:space:]$guess]/*}"
The thing I want to do now is echo the alphabet, but leave out the letters that the user already tried, so in this case show the full alphabet without the L.
I already tried to do it the same way as I shown just yet, but it won't quite work.
If you need any more info please let me know.
Thanks,
Tim
You don't show what you tried, but parameter expansion works fine.
$ alphabet=abcdefghijklmnopqrstuvwxyz
$ word="hello world"
$ guesses=aetl
$ echo "${word//[^[:space:]$guesses]/*}"
*ell* ***l*
$ echo "${alphabet//[$guesses]/*}"
*bcd*fghijk*mnopqrs*uvwxyz
First store both strings in files where they are stored one char per line:
sed 's/./&\n/g' | sort <<< $guess > guessfile
sed 's/./&\n/g' | sort <<< $word > wordfile
Then we can filter the words that are only present in one of the files and paste the lines together as a string:
grep -xvf guessfile wordfile | paste -s -d'\0'
And of course we clean up after ourselves:
rm wordfile
rm guessfile
If the output is not correct, try switching arguments in grep (i.e. wordfile guessfile instead of guessfile wordfile).

How to search for numbers in filename/data in shell script

I have 10 files in a folder. All with similar pattern with text and number:
ABCDEF20141010_12345.txt
ABCDEF20141010_23456.txt
ABCDEF20141010_34567.txt
...
I need to process these files in a loop.
for filename in `ls -1 | egrep "ABCDEF[0-9]+\_[0-9]+.txt"`
do
<code>
done
Above egrep code, is not going inside the loop. Can you please help me in modifying this search?
You don't have to use ls and grep. It's working with shell-only functionalities:
for filename in ABCDEF[0-9]*_[0-9]*.txt
do
echo $filename
#do whatever
done

Different output for pipe in script vs. command line

I have a directory with files that I want to process one by one and for which each output looks like this:
==== S=721 I=47 D=654 N=2964 WER=47.976% (1422)
Then I want to calculate the average percentage (column 6) by piping the output to AWK. I would prefer to do this all in one script and wrote the following code:
for f in $dir; do
echo -ne "$f "
process $f
done | awk '{print $7}' | awk -F "=" '{sum+=$2}END{print sum/NR}'
When I run this several times, I often get different results although in my view nothing really changes. The result is almost always incorrect though.
However, if I only put the for loop in the script and pipe to AWK on the command line, the result is always the same and correct.
What is the difference and how can I change my script to achieve the correct result?
Guessing a little about what you're trying to do, and without more details it's hard to say what exactly is going wrong.
for f in $dir; do
unset TEMPVAR
echo -ne "$f "
TEMPVAR=$(process $f | awk '{print $7}')
ARRAY+=($TEMPVAR)
done
I would append all your values to an array inside your for loop. Now all your percentages are in $ARRAY. It should be easy to calculate the average value, using whatever tool you like.
This will also help you troubleshoot. If you get too few elements in the array ${#ARRAY[#]} then you will know where your loop is terminating early.
# To get the percentage of all files
Percs=$(sed -r 's/.*WER=([[:digit:].]*).*/\1/' *)
# The divisor
Lines=$(wc -l <<< "$Percs")
# To change new lines into spaces
P=$(echo $Percs)
# Execute one time without the bc. It's easier to understand
echo "scale=3; (${P// /+})/$Lines" | bc

shell script : how to replace file name

I want to change some file names with full path similar to this:
/home/guest/test
⟶ /home/guest/.test.log
I tried the command below but it cannot search "/"
string="/home/guest/test"
substring="/"
replacement="/."
echo ${string/%substring/replacement}.log
You can do something like:
for file in /home/guest/*; do
name=${file##*/}
path=${file%/*}
mv "$file" "$path"'/.'"$name"'.log'
done
Created using bash on a mac, so it might work with whatever shell you are using...
string="/home/guest/test"
echo $string | sed 's/\/\([^\/]\{0,\}\)$/\/.\1.log/'
Using simple shell string replacement wasn't going to work since I know of no way you can target the last occurrence of the / sign as the only replacement.
Update:
Actually I came to think of a alternative way if you know that it is always "/two/directories/in"
string="/home/guest/test"
firstpartofstring=$(echo $string | cut -d\/ -f1-3)
lastpartofstring=$(echo $string | cut -d\/ -f4)
echo ${firstpartofstring}/.${lastpartofstring}.log

Resources