Bash - How to Match Files Names to Use in Loop

How to loop over files in directory and change path and add suffix to filename

A couple of notes first: when you use Data/data1.txt as an argument, should it really be /Data/data1.txt (with a leading slash)? Also, should the outer loop scan only for .txt files, or all files in /Data? Here's an answer, assuming /Data/data1.txt and .txt files only:

#!/bin/bash
for filename in /Data/*.txt; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt"
done
done

Notes:

  • /Data/*.txt expands to the paths of the text files in /Data (including the /Data/ part)
  • $( ... ) runs a shell command and inserts its output at that point in the command line
  • basename somepath .txt outputs the base part of somepath, with .txt removed from the end (e.g. /Data/file.txt -> file)

If you needed to run MyProgram with Data/file.txt instead of /Data/file.txt, use "${filename#/}" to remove the leading slash. On the other hand, if it's really Data not /Data you want to scan, just use for filename in Data/*.txt.

How to loop through files matching variables and display only the file name in bash?

i've nested an if loop that uses regex inside the for loop.

i left the original filename including extension as the 'file' variable in case you ever want to filter by extension.

just edit the regex variable to capture different kinds of things.

update: edited to be able to take two arguments from command line, and to have to match both to print filename

    #!/usr/bin/bash

regex=$1
regex2=$2

for filename in ~/notes/*; do
file=`basename "$filename"`
filestrip=${file%.*}

if [[ $filestrip =~ $regex ]] && [[ $filestrip =~ $regex2 ]]; then
echo $filestrip
fi

done

If filename matches pattern do something (for-loop, case-statement)

You can split the file names using the read command.

for FILE in ../pdf/*.pdf; do
[[ ! -f "$FILE" ]] && continue # check if $FILE is a file
IFS=. read kind month year ext <<< "${FILE#./pdf/}"

case "$kind" in
[Ii]nsurance*) # matching pattern in filename
rsync command
;;
Provider1*)
rsync command
;;
...
...
esac
done

  1. "${FILE#./pdf/}" expands to the value of FILE, minus the leading ./pdf/
  2. <<< feeds a string to the standard input of a command.
  3. read takes a line of input, performs word-splitting based on the first character of the value of IFS (here, a .), and puts resulting word each variable whose name is passed as an argument.

So if FILE=./pdf/Insurance.January.2020.pdf, then

IFS=. read kind month year ext <<< "${FILE#./pdf/}"

feeds the string Insurance.Januray.2020.pdf to read, which then performs the assignments

kind=Insurance
month=January
year=2020
ext=pdf

Get only file name in variable in a for loop

You need two lines; chained operators aren't allowed.

f=${f##*/}  # Strip the directory
f=${f%%.*} # Strip the extensions

Or, you can use the basename command to strip the directory and one extension (assuming you know what it is) in one line.

f=$(basename "$f" .txt)

loop over files and extract part of filename

Just re-assign the loop variable at the beginning of each iteration:

for sample in *.vcf; do
sample=${sample%_*}
# do stuff here
done

Bash loop to remove files matching name structure

Not sure why will you need the loop but here are some suggestions:

ls *.mp3 | grep '(1)' | xargs -d"\n" rm

this will get all the .mp3 files that have the expression (1) in them e.g. abc(1).mp3 etc

if you want to have a broader reach or more dynamicity in your approach I will recommend using regex in grep:

ls *.mp3 | grep -P "regex-here" | xargs -d"\n" rm

if you want to delete few other type of files e.g. mp4 etc as well in the same command then use:

ls *.{mp3,mp4,mpeg} | grep -P "regex-here" | xargs -d"\n" rm

you can also use regex and delete with the help of find:

find -iregex 'regex-here' -delete


Related Topics



Leave a reply



Submit