need a unix script that will validate that there is no space in a given path - linux

My requirement is simple
I have a file with a list of paths provided in a line.
Eg:
/etc/home
/var/www/
I need a command to validate that there are no space characters in between the path like: /var/ www/
How can I achieve this validation?

This should help. It uses the Internal Field Separator.
#!/bin/sh
if [ ! $1 ]; then
echo Filename parameter expected
exit
fi
export IFS=$'\n'
for i in `cat $1`
do
if [ `echo $i | grep ' ' ` ]; then
echo Spaces found in [$i]
else
echo No spaces found in [$i]
fi
done

Related

Convert nth character of all filenames in a directory to uppercase in bash

For files like :
_aaa.txt
_bbb.txt
_ccc.txt
I want to convert them to :
_aAa.txt
_bBb.txt
Any idea how to do this ?
In plain bash, using only shell parameter expansions to perform the conversion:
#!/bin/bash
n=3
for file in *; do
[[ -f $file ]] || continue
suffix=${file:n-1}
mv -i "$file" "${file:0:n-1}${suffix^}"
done
Check the output of the following
#!/bin/bash
for filename in *; do
newname=$(sed 's/./\U&/3' <<< "$filename")
echo "$filename --> $newname"
# mv $filename $newname
done
Then remove the #, if the filename printed is correct
If rename command is available, please try:
rename 's/^(..)(.)/$1\U$2/' *.txt

extracting files that doesn't have a dir with the same name

sorry for that odd title. I didn't know how to word it the right way.
I'm trying to write a script to filter my wiki files to those got directories with the same name and the ones without. I'll elaborate further.
here is my file system:
what I need to do is print a list of those files which have directories in their name and another one of those without.
So my ultimate goal is getting:
with dirs:
Docs
Eng
Python
RHEL
To_do_list
articals
without dirs:
orphan.txt
orphan2.txt
orphan3.txt
I managed to get those files with dirs. Here is me code:
getname () {
file=$( basename "$1" )
file2=${file%%.*}
echo $file2
}
for d in Mywiki/* ; do
if [[ -f $d ]]; then
file=$(getname $d)
for x in Mywiki/* ; do
dir=$(getname $x)
if [[ -d $x ]] && [ $dir == $file ]; then
echo $dir
fi
done
fi
done
but stuck with getting those without. if this is the wrong way of doing this please clarify the right one.
any help appreciated. Thanks.
Here's a quick attempt.
for file in Mywiki/*.txt; do
nodir=${file##*/}
test -d "${file%.txt}" && printf "%s\n" "$nodir" >&3 || printf "%s\n" "$nodir"
done >with 3>without
This shamelessly uses standard output for the non-orphans. Maybe more robustly open another separate file descriptor for that.
Also notice how everything needs to be quoted unless you specifically require the shell to do whitespace tokenization and wildcard expansion on the value of a token. Here's the scoop on that.
That may not be the most efficient way of doing it, but you could take all files, remove the extension, and the check if there isn't a directory with that name.
Like this (untested code):
for file in Mywiki/* ; do
if [ -f "$d" ]; then
dirname=$(getname "$d")
if [ ! -d "Mywiki/$dirname" ]; then
echo "$file"
fi
fi
done
To List all the files in current dir
list1=`ls -p | grep -v /`
To List all the files in current dir without extension
list2=`ls -p | grep -v / | sed 's/\.[a-z]*//g'`
To List all the directories in current dir
list3=`ls -d */ | sed -e "s/\///g"`
Now you can get the desired directory listing using intersection of list2 and list3. Intersection of two lists in Bash

scp all log files of pattern filename_date between 2 dates in shell script

My log file is in the format upd_yyyymmdd_slr.stats. I want to copy all files from a server to my local server between 2 dates, for example.
I want all files having dates in log file as 20151228 and 20160103 means I want to copy the below files from a set of many files.
upd_20151228_slr.stats
upd_20151229_slr.stats
upd_20151230_slr.stats
upd_20151231_slr.stats
upd_20160101_slr.stats
upd_20160102_slr.stats
upd_20160103_slr.stats
I'm using the below command but it is not working
scp server:/reports/logs/upd_20[15-16][12-01][29-03]*slr* ./log_files
Please find me the best way I can do in Linux as well as in shell scripting
Check out this script:
#!/bin/bash
for i in `ls upd_*_slr.stats`; do
# First strip off prefix and suffix strings.
s=`echo $i | sed 's/upd_//g' | sed 's/_slr.stats//g'`
if [[ $s -ge 20151230 && $s -le 20160102 ]]; then # Modify dates as needed
echo $i
cp $i /path/to/dest/dir
fi
done
EDIT:
In case of a remote server one could try this:
#!/bin/bash
for i in `ssh username#remoteaddress ls /path/to/dir/upd_*_slr.stats`; do
i=${i##*/}
# First strip off extra strings leaving only date.
s=`echo $i | sed 's/upd_//g' | sed 's/_slr.stats//g'`
if [[ $s -ge 20151230 && $s -le 20160102 ]]; then # Modify dates as needed
echo $i
scp username#remoteaddress:/path/to/dir/$i /path/to/dest/dir
fi
done

What is the error in this shell script

I never used shell script, but now I have to , here is what I'm trying to do :
#!/bin/bash
echo running the program
./first
var = ($(ls FODLDER |wc -l)) #check how many files the folder contains
echo $var
if( ["$var" -gt "2"] #check if there are more the 2file
then ./second
fi
the scriopt crashes at the if statement. how may I solve this
Many:
var = ($(ls FODLDER |wc -l))
This is wrong, you cannot have those spaces around =.
if( ["$var" -gt "2"]
Your ( is not doing anything there, so it has to be deleted. Also, you need spaces around [ and ].
All together, this would make more sense:
#!/bin/bash
echo "running the program"
./first
var=$(find FOLDER -maxdepth 1 -type f|wc -l) # better find than ls
echo "$var"
if [ "$var" -gt "2" ]; then
./second
fi
Note:
quote whenever you echo, specially when handling variables.
see another way to look for files in a given path. Parsing ls is kind of evil.
indent your code for better readibility.
Edit your script.bash file as follow:
#!/bin/env bash
dir="$1"
echo "running the program"
./first
dir_list=( $dir/* ) # list files in directory
echo ${#dir_list[#]} # count files in array
if (( ${#dir_list[#]} > 2 )); then # test how many files
./second
fi
Usage
script.bash /tmp/
Explaination
You need to learn bash to avoid dangerous actions!
pass the directory to work with as first argument in the command line (/tmp/ → `$1)
use glob to create an array (dir_list) containing all file in given directory
count items in array (${#dir_list[#]})
test the number of item using arithmetic context.

Creating a pathname to check a file doesn't exist there / Permission denied error

Hello from a Linux Bash newbie!
I have a list.txt containing a list of files which I want to copy to a destination($2). These are unique images but some of them have the same filename.
My plan is to loop through each line in the text file, with the copy to the destination occurring when the file is not there, and a mv rename happening when it is present.
The problem I am having is creating the pathname to check the file against. In the code below, I am taking the filename only from the pathname, and I want to add that to the destination ($2) with the "/" in between to check the file against.
When I run the program below I get "Permission Denied" at line 9 which is where I try and create the path.
for line in $(cat list.txt)
do
file=$[ basename $line ]
path=$[ $2$file ]
echo $path
if [ ! -f $path ];
then
echo cp $line $2
else
echo mv $line.DUPLICATE $2
fi
done
I am new to this so appreciate I may be missing something obvious but if anyone can offer any advice it would be much appreciated!
Submitting this since OP is new in BASH scripting no good answer has been posted yet.
DESTINATION="$2"
while read -r line; do
file="${line##*/}"
path="$2/$file"
[[ ! -f $path ]] && cp "$line" "$path" || mv "$line" "$path.DUP"
done < list.txt
Don't have logic for counting duplicates at present to keep things simple. (Which means code will take care of one dup entry) As an alternative you get uniq from list.txt beforehand to avoid the duplicate situation.
#anubhava: Your script looks good. Here is a small addition to it to work with several dupes.
It adds a numer to the $path.DUP name
UniqueMove()
{
COUNT=0
while [ -f "$1" ]
do
(( COUNT++ ))
mv -n "$1" "$2$COUNT"
done
}
while read -r line; do
file="${line##*/}"
path="$2/$file"
[[ ! -f $path ]] && cp "$line" "$path" || UniqueMove "$line" "$path.DUP"
done < list.txt

Resources