Print strings from a particular position in each line

I am using bash in Fedora 30

From the below lines ( ls -l output), how can I print whatever is between the strings ' status_ ' and ' .log '

$ ls -l | grep -i status 
-rw-rw-r--. 1 sysadmin sysadmin 378530 Nov 11 21:58 status_vsbm1.log
-rw-rw-r--. 1 sysadmin sysadmin 428776 Nov 11 21:58 status_OSMPRD1.log
-rw-rw-r--. 1 sysadmin sysadmin 393977 Nov 11 21:58 status_fxmdbp1.log
-rw-rw-r--. 1 sysadmin sysadmin 557476 Nov 11 21:58 status_cgsm1.log
-rw-rw-r--. 1 sysadmin sysadmin 555879 Nov 11 21:58 status_cgsm2.log
-rw-rw-r--. 1 sysadmin sysadmin 553381 Nov 11 21:58 status_cgsm3.log
-rw-rw-r--. 1 sysadmin sysadmin 556506 Nov 11 21:58 status_cgsm4.log
-rw-rw-r--. 1 sysadmin sysadmin 577325 Nov 11 21:58 status_cgsm5.log
-rw-rw-r--. 1 sysadmin sysadmin 415795 Nov 11 21:58 status_SOACAT1.log
-rw-rw-r--. 1 sysadmin sysadmin 449812 Nov 11 21:58 status_INTPHLK11.log
-rw-rw-r--. 1 sysadmin sysadmin 455842 Nov 11 21:58 status_INTPHLK21.log
-rw-rw-r--. 1 sysadmin sysadmin 447726 Nov 11 21:58 status_wmeaidbp1.log
-rw-rw-r--. 1 sysadmin sysadmin 385274 Nov 11 21:58 status_wmsmpdbp1.log
$ 

Expected output :

vsbm1
OSMPRD1
fxmdbp1
cgsm1
.
.
.

there are probably a million ways to do it more elegantly but I would probably just try this

ls -ali | rev | cut -d' ' -f 1 | cut -c 1-7 | cut -c 5-99 | rev

Something like this, also not very elegant:

ubuntu# egrep -o '_.*[0-9]' test.log | cut --complement -c  1
vsbm1
OSMPRD1
fxmdbp1
cgsm1
cgsm2
cgsm3
cgsm4
cgsm5
SOACAT1
INTPHLK11
INTPHLK21
wmeaidbp1
wmsmpdbp1

Or, in your case:

ls -l | grep -i status  | egrep -o '_.*[0-9]'  | cut --complement -c  1

There must be 100s of ways to do this which are much nicer ... LOL

Like ...

ls -l | egrep -o 'status_.*[0-9]' | cut --complement -c1-7

PS: kraljic .... You should really try yourself (post code) when asking a question like this. Show your work and what you tried yourself. You have over 100 posts here. Try yourself before asking, please.

1 Like

Two stage process not using ls :

for f in status_*.log
do
   f1="${%*_}
   printf "%s\n" "${f1#.log}"
done

Which can be written as a single line:

for f in status_*.log; do f1="${%*_}; printf "%s\n" "${f1#.log}"; done
ls | sed -n 's/^status_\(.*\)[.]log$/\1/p'
2 Likes
ls | awk -F"status_|[.]log" ' { print $2 } '
1 Like

Using external programs (such as cut , *grep , sed , awk or others) are a dire waste of precious resources as well as processes.

It is not clear what the two rev s should accomplish, except making the line non-standard and GNU-dependant.

This is using several non-standard GNU-specific extensions and will therefore only work with the GNU versions of the used utilities. It is dangerous to suggest such solutions, at least when foregoing a proper disclaimer that it won't work in most environments.

This is - in principle - a valid solution although it seems the "#" and "%" operators have been confused, a double quote is missing and a few typos like

f1="${%*_}

will prevent proper execution. It is not necessary to use different variables for the expansion either:

for f in status_*.log; do f="${f%.log}"; printf "%s\n" "${f#status_}"; done
2 Likes

I do condone coding practices mentioned and standard compliance.
One should produce shell code to run anywhere (or any code), if able.

But, the OP posted his operating system is fedora linux and didn't not request a posix compliant shell code to be produced.
As for better way, it is welcomed and encouraged to post better code with proper explanation.
Which member stomp offered.

It is also worth to mention the negligible impact on modern multi-core computers any command provided here has, regardless of quality.
Even with alot of files.

Regards
Peasant.

Hi.

Using pcregrep :

pcregrep -o1 'status_(.*?)[.]log' <( ls *status* )

The -o1 extracts parentheses group number 1.
and will produce:

INTPHLK11
INTPHLK21
OSMPRD1
SOACAT1
cgsm1
cgsm2
cgsm3
cgsm4
cgsm5
fxmdbp1
vsbm1
wmeaidbp1
wmsmpdbp1

On a system like:

OS, ker|rel, machine: Linux, 3.16.0-7-amd64, x86_64
Distribution        : Debian 8.11 (jessie) 
pcregrep version 8.35 2014-04-04

More details on pcregrep:

pcregrep        a grep with Perl-compatible regular expressions. (man)
Path    : /usr/bin/pcregrep
Version : 2014-04-04
Type    : ELF 64-bit LSB shared object, x86-64, version 1 ( ...)
Help    : probably available with -h,--help
Repo    : Debian 8.11 (jessie) 

Best wishes ... cheers, drl