This question already has answers here:
How to loop over files in directory and change path and add suffix to filename
(6 answers)
Closed 3 years ago.
I am trying to loop through every file in a user specified directory.
Here's my code:
clear
echo "enter the directory path: \n"
read directory
for file in $directory; do
echo $file
done
My input, e.g.: /home/user/Downloads
Output I get: /home/user/Downloads
If I use
clear
for file in *; do
echo $file
done
It works, but it shows only the contenets of current directory
If you only want the files non-recursively in the current directory, combine what you have:
read -p 'Enter the directory path: ' directory
for file in "$directory"/*; do
echo "$file"
done
If you want to loop recursively and you have bash 4, it's not much harder:
shopt -s globstar
for file in "$directory"/**/*; do …
But if you only have bash 3, you'd be better off using find.
find "$directory"
Try
dir="${GOL_HOME}/test_dir"
file="file_*.csv"
for file in `cd ${dir};ls -1 ${file}` ;do
echo $file
done
You can write this script
#!/bin/bash
clear
echo "enter the directory path: \n"
read directory
for file in $directory/*; do
echo $file
done
Related
I have a shell script which takes an location input from a text file. I had loop in the script to read line(location) and change directory to the location and list the files.
In the below the location directory "switch" changes because this location may not exists on the all the servers. I have to pass this directory as an argument to the file and pass this location to the script.
locations.txt has below content.
/usr/test/home/process_file/switch/process.txt
shell script:
for i in `cat locations`;
do
echo $line
cd $i
if [ -d "$i" ]
then
cd $i
pwd
ls -ltr
else
exit
fi
done
Storing a filename in a file seems a little inefficient.
Don't read lines with for
cd will return non-zero if the directory does not exist.
while IFS= read -r dir; do
if cd "$dir" 2>/dev/null; then
pwd
ls -ltr
else
echo "no such directory: $dir"
fi
done < /usr/test/home/process_file/switch/process.txt
This question already has answers here:
Check if a file exists with a wildcard in a shell script [duplicate]
(21 answers)
Closed 3 years ago.
I want to check if file exists but only checking if some the filename exists
For example in some folder I have these files (Date format: AAAAMMDD):
Rejets_20190112.csv.zip
Rejets_20190312.csv.zip
Rejets_20190314.csv.zip
I want to check if there is a file that begins with Rejet_DAP_201903 exists in that folder. In other word I want to check if Rejet_DAP file with current year and month exist, the day doesn't matter.
Here's what I tried to do in my script:
jour=`date +%d`
mois=`date +%m`
annee=`date +%Y`
FILE="/appli/project/echanges/RTY/receptions/Rejet_${annee}${mois}"_*
if [[ -e $FILE ]]
then
echo "FILE EXISTS"
else
echo "FILE DOES NOT EXIST"
fi
You have the directory path and the file pattern that you are looking for.
The ls command can be used to list files based on patterns.
All commands return an integer value after execution. 0 means the execution finished successfully. Any non-zero value means error.
ls will return a non-zero value if no files match the pattern.
That return code you can use within the if statement.
#!/bin/bash
jour=`date +%d`
mois=`date +%m`
annee=`date +%Y`
/appli/project/echanges
dir="/appli/project/echanges/RTY/receptions"
file_prefix="Rejet_DAP_"
if ls $dir/${file_prefix}${annee}${mois}* > /dev/null 2>&1
then
echo "FILE EXISTS"
else
echo "FILE DOES NOT EXIST"
fi
The #!/bin/bash line is called a shebang line and I highly recommend using it in your scripts.
The > /dev/null 2>&1 is so that you don't get output from the ls command and only have your output displayed.
You can use find for this
$ if [[ `find /appli/project/echanges/RTY/receptions/ -type f |grep -i Rejet_DAP_${annee}${mois}|wc -l` -gt 0 ]] ; then
echo "FILE EXISTS"
else
echo "FILE DOES NOT EXIST"
fi
I am relatively new to shell scripting. I am writing a script to compress all the files in current and target directory. I have found success in compressing the files of a current directory but I'm unable to write a script for compressing files in a target directory can anyone guide me?
I want to do something like this
% myCompress -t /home/users/bigFoot/ pdf ppt jpg
next time try to spread your code (it will make it easier to answer):
#!/bin/bash
if [[ $# == 0 ]]; then
echo "This shell script compress files with a specific extensions"
echo "Call Syntax: compress <extension_list>"
exit
fi
for ext in $*; do
for file in ls *.$ext; do
gzip -k $file
done
done
Mistakes made
1) $* - all args coming after command - so.... -t and path are not $ext variables
2) ls *.$ext is red in loop as 2 strings "ls and *.$ext" should be written as $(ls *.$ext) to get ls command executed
My script for your request
#!/bin/bash
script_name=`basename "$0"`
if [[ $# == 0 ]]; then
echo "This shell script compress files with a specific extensions"
echo "Call Syntax: $script_name <dirctories_list> <extension_list>"
exit
fi
# check if $1 is a directory
path=". "
file_type=""
for check_type in $* ; do
if [[ -d $check_type ]]; then
path=$path$check_type" "
else
file_type=$file_type"*."$check_type" "
fi
done
echo paths to gzip $path
echo files type to check "$file_type"
for x in $path; do
cd $x
for file in $(ls $file_type); do
gzip $file
done
cd -
done
Explanation
1) basename "$0" - get scripts name - it is more generic for usage - in case you change script's name
2) path=". " - variable hold a string of all directories to be compressed, your request is to run it also on current directory ". "
file_type="" - variable hold a string of all extensions to be compressed in $path string
3) running a loop on all input ARGS and concatenate directories names to $path string and other file types to $file_type
4) for each of the directories inserted to script:
i. cd $x - enter directorie
ii. gzip - compress all files with inserted extensions
iii. cd - - go back to base directories
Check gzip
I'm not familiar with the gzip command , check that you have -k flag
Anyone able to help me out? I have a shell script I am working on but for the loop below the command after "echo "first file is $firstbd" is not being executed.. the $PROBIN/proutil ?? Not sure why this is...
Basically I have a list of files in a directory (*.list), I grab them and read the first line and pass it as a parameter to the cmdlet then move the .list and the content of the .list to another directory (the .list has a list of files with full path).
for i in $(ls $STAGEDIR/*.list); do
echo "Working with $i"
# grab first .bd file
firstbd=`head -1 $i`
echo "First file is $firstbd"
$PROBIN/proutil $DBENV/$DBNAME -C load $firstbd tenant $TENANT -dumplist $STAGEDIR/$i.list >> $WRKDIR/$i.load.log
#move the list and its content to finished folder
binlist=`cat $i`
for movethis in $binlist; do
echo "Moving file $movethis to $STAGEDIR/finished"
mv $movethis $STAGEDIR/finished/
done
echo "Finished working with list $i"
echo "Moving it to $STAGEDIR/finished"
mv $i $STAGEDIR/finished/
done
The error I was getting is..
./tableload.sh: line 107: /usr4/dlc/bin/proutil /usr4/testdbs/xxxx2 -C load /usr4/dumpdir/xxxxx.bd tenant xxxxx -dumplist /usr4/dumpdir/PUB.xxxxx.list >> /usr4/dumpdir/PUB.xxxx.list.load.log: A file or directory in the path name does not exist... however if I run "/usr4/dlc/bin/proutil"
The fix was to remove ">> $WRKDIR/$i.load.log".. the binary utility wouldn't run when trying to output results to file.. strange..
A couple of really bad practices here
parse the output of ls
not quoting variables
iterating the lines of a file with cat and for
As shelter comments, you don't check that you've created all the directories in the path for your log file.
A rewrite:
for i in "$STAGEDIR"/*.list; do
echo "Working with $i"
# grab first .bd file
firstbd=$(head -1 "$i")
echo "First file is $firstbd"
# ensure the output directory exists
logfile="$WRKDIR/$i.load.log"
mkdir -p "$(dirname "$logfile")"
"$PROBIN"/proutil "$DBENV/$DBNAME" -C load "$firstbd" tenant "$TENANT" -dumplist "$STAGEDIR/$i.list" >> "$logfile"
# move the list and its content to finished folder
while IFS= read -r movethis; do
echo "Moving file $movethis to $STAGEDIR/finished"
mv "$movethis" "$STAGEDIR"/finished/
done < "$i"
echo "Finished working with list $i"
echo "Moving it to $STAGEDIR/finished"
mv "$i" "$STAGEDIR"/finished/
done
I've written bash script to open a file passed as an argument and write it into another file. But my script will work properly only if the file is in the current directory. Now I need to open and write the file that is not in the current directory also.
If compile is the name of my script, then ./compile next/123/file.txt should open the file.txt in the passed path. How can I do it?
#!/bin/sh
#FIRST SCRIPT
clear
echo "-----STARTING COMPILATION-----"
#echo $1
name=$1 # Copy the filename to name
find . -iname $name -maxdepth 1 -exec cp {} $name \;
new_file="tempwithfile.adb"
cp $name $new_file #copy the file to new_file
echo "compiling"
dir >filelist.txt
gcc writefile.c
run_file="run_file.txt"
echo $name > $run_file
./a.out
echo ""
echo "cleaning"
echo ""
make clean
make -f makefile
./semantizer -da <withfile.adb
Your code and your question are a bit messy and unclear.
It seems that you intended to find your file, given as a parameter to your script, but failed due to the maxdepth.
If you are given next/123/file.txt as an argument, your find gives you a warning:
find: warning: you have specified the -maxdepth option after a
non-option argument -iname, but options are not positional (-maxdepth
affects tests specified before it as well as those specified after
it). Please specify options before other arguments.
Also -maxdepth gives you the depth find will go to find your file until it quits. next/123/file.txt has a depth of 2 directories.
Also you are trying to copy the given file within find, but also copied it using cp afterwards.
As said, your code is really messy and I don't know what you are trying to do. I will gladly help, if you could elaborate :).
There are some questions that are open:
Why do you have to find the file, if you already know its path? Do you always have the whole path given as an argument? Or only part of the path? Only the basename ?
Do you simply want to copy a file to another location?
What does your writefile.c do? Does it write the content of your file to another? cp does that already.
I also recommend using variables with CAPITALIZED letters and checking the exit status of used commands like cp and find, to check if these failed.
Anyway, here is my script that might help you:
#!/bin/sh
#FIRST SCRIPT
clear
echo "-----STARTING COMPILATION-----"
echo "FILE: $1"
[ $# -ne 1 ] && echo "Usage: $0 <file>" 1>&2 && exit 1
FILE="$1" # Copy the filename to name
FILE_NEW="tempwithfile.adb"
cp "$FILE" "$FILE_NEW" # Copy the file to new_file
[ $? -ne 0 ] && exit 2
echo
echo "----[ COMPILING ]----"
echo
dir &> filelist.txt # list directory contents and write to filelist.txt
gcc writefile.c # ???
FILE_RUN="run_file.txt"
echo "$FILE" > "$FILE_RUN"
./a.out
echo
echo "----[ CLEANING ]----"
echo
make clean
make -f makefile
./semantizer -da < withfile.adb