0

I'm looking to extract part of filename which I"m currently using position but it's not working as desired output.

Sample data:

ls -a *0728*dat | sort

amnbmnbm_jnjmnm_sd_07282019_14_13_17.dat
amnbmnb_kjhkj_07282019_11_23_22.dat
njnkjnjk_AbnBCBB_DE_07282019_07_09_04.dat

I'm looking to extract the file part from the filename everything leftside from the date on wards including underscore(_) and assign it to vairable

Desired output:

variable file is something it needs to hold the values, so that I can pass in for loop

file:

amnbmnbm_jnjmnm_sd_
amnbmnb_kjhkj_
njnkjnjk_AbnBCBB_DE_


for file_name in "${file[@]}"
do

echo " file_name=$file_name"

done

Desired output:

amnbmnbm_jnjmnm_sd_
amnbmnb_kjhkj_
njnkjnjk_AbnBCBB_DE_
0

3 Answers 3

1

Perhaps:

for file_name in *0728*dat
do
  printf '%s\n' "${file_name%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9]_[0-9][0-9]_[0-9][0-9].dat}"
done

This strips from the end of each filename the pattern of: 8 digits, underscore, 2 digits, underscore, 2 digits, underscore, 2 digits, then .dat.

0

using sed:

ls -a *0728*dat | sed 's/[0-9].*//'
amnbmnb_kjhkj_
amnbmnbm_jnjmnm_sd_
njnkjnjk_AbnBCBB_DE_

or

ls -a *0728*dat | sed "s/[0-9]\{8\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}\.dat$//"
0

The following requires bash 4.4 or newer, GNU find and GNU sed (or, at least a find and a sed that support NUL as the output/input separator):

$ mapfile -d '' files < <(find . -maxdepth 1 -type f -iname '*0728*.dat' -print0 | 
    sed -z 's:^\./::; s/[0-9][0-9_]\+.dat//')

This populates a bash array (files) with the matching filenames in the current directory after they've had the leading ./ and the date & time & .dat extension stripped by sed. It uses NUL as the record (i.e. filename) separator to avoid any potential issues with spaces, line-feeds, shell meta-characters, etc in any of the filenames.

find is used because you should never use the output of ls as input to other programs or as arguments on another program's command-line - it is unsafe and unreliable. See Why not parse ls (and what to do instead)?

The find command can, of course, be modified to find files matching different patterns, or in sub-directories, etc.

Example:

$ touch amnbmnbm_jnjmnm_sd_07282019_14_13_17.dat amnbmnb_kjhkj_07282019_11_23_22.dat \
    njnkjnjk_AbnBCBB_DE_07282019_07_09_04.dat

$ mapfile -d '' files < <(find . -maxdepth 1 -type f -iname '*0728*.dat' -print0 | 
    sed -z 's:^\./::; s/[0-9][0-9_]\+.dat//')

$ typeset -p files
declare -a files=([0]="amnbmnbm_jnjmnm_sd_" [1]="amnbmnb_kjhkj_" [2]="njnkjnjk_AbnBCBB_DE_")

$ printf '%s\n' "${files[@]}"
amnbmnbm_jnjmnm_sd_
amnbmnb_kjhkj_
njnkjnjk_AbnBCBB_DE_

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.