blank space in directory name causing error - bash

Hi I have many directories which have blank space in their names.I have some scripts to be run on them.
Here is an example script
#!/bin/bash
docid='/home/deel/PDF/rant/spr 2008 Shree rose Visheshank'
p=1
while [ $p -lt 117 ]; do
cp $docid/$p.pdf ./
p=$p+1
done
Upon executing the above script I get following errors
cp: cannot stat `/home/deel/PDF/rant/spr': No such file or directory
cp: cannot stat `2008': No such file or directory
cp: cannot stat `Shree': No such file or directory
cp: cannot stat `rose': No such file or directory
cp: cannot stat `Visheshank/1.pdf': No such file or directory
./d2.sh: line 5: [: 1+1: integer expression expected
I have tried using double quotes "" but the results are same.
What changes should I do?

This line:
cp $docid/$p.pdf ./
should read:
cp "$docid/$p.pdf" ./
Example:
$ a='abc def'
$ ls $a
ls: abc: No such file or directory
ls: def: No such file or directory
$ ls "$a"
ls: abc def: No such file or directory
And arithmetic goes like:
p=$[p+1]
Example:
$ p=1
$ q=$[p+1]
$ echo $p $q
1 2

You need to quote the name containing spaces with double quotes. Moreover, p=$p+1 does not do what you expect. Here is the corrected loop:
for p in `seq 116`; do
cp "$docid/$p.pdf" ./
done

Related

failed to copy of a series of file using the for loop, cannot find the problem

I was trying to copy some files with numbering with for i in {};do cp ***;done, but I have encountered an error.
$ for i in {0..2};do cp ./CTCC_noSDS_0$i_hg19.bwt2pairs.validPairs 3_dataset_pool/;done
cp: cannot stat ‘./CTCC_noSDS_0.bwt2pairs.validPairs’: No such file or directory
cp: cannot stat ‘./CTCC_noSDS_0.bwt2pairs.validPairs’: No such file or directory
cp: cannot stat ‘./CTCC_noSDS_0.bwt2pairs.validPairs’: No such file or directory
The file name look like below:
-rw-r--r-- 1 jiangxu lc_lc 456M Nov 12 20:22 CTCC_noSDS_00_hg19.bwt2pairs.validPairs
-rw-r--r-- 1 jiangxu lc_lc 466M Nov 12 20:23 CTCC_noSDS_01_hg19.bwt2pairs.validPairs
-rw-r--r-- 1 jiangxu lc_lc 473M Nov 12 20:23 CTCC_noSDS_02_hg19.bwt2pairs.validPairs
I can cp the file one by one manually but can not use the for loop. It seems that the system just ignored the $i for no reason, So, could anyone tell me what is the problem with the command?
Using a similar method to the OP
You can do something like this (call this script b.bash):
#!/bin/bash
DST_DIR=./mydir/
SRC_DIR=./
for i in {1..5}; do
echo "[*] Trying to find files with number $i"
if [ "$i" -lt 10 ]; then
potential_file="$SRC_DIR/CTCC_noSDS_0${i}_hg19.bwt2pairs.validPairs"
else
potential_file="$SRC_DIR/CTCC_noSDS_${i}_hg19.bwt2pairs.validPairs"
fi
if [ -f "$potential_file" ]; then
echo "[!] Moving $potential_file"
cp "$potential_file" "$DST_DIR"
fi
done
Let us say we have the following in the current directory:
$ ls -1
b.bash
CTCC_noSDS_00_hg19.bwt2pairs.validPairs
CTCC_noSDS_01_hg19.bwt2pairs.validPairs
CTCC_noSDS_02_hg19.bwt2pairs.validPairs
CTCC_noSDS_12_hg19.bwt2pairs.validPairs
mydir
And let us say we want to copy these files to mydir. If we run the above script, we see this output:
$ ./b.bash
[*] Trying to find files with number 1
[!] Moving .//CTCC_noSDS_01_hg19.bwt2pairs.validPairs
[*] Trying to find files with number 2
[!] Moving .//CTCC_noSDS_02_hg19.bwt2pairs.validPairs
[*] Trying to find files with number 3
[*] Trying to find files with number 4
[*] Trying to find files with number 5
Then looking in mydir we see the files:
$ ls -1 mydir/
CTCC_noSDS_01_hg19.bwt2pairs.validPairs
CTCC_noSDS_02_hg19.bwt2pairs.validPairs
Note that the above for loop only goes to 5. You can modify that as
you see fit.
Note the if statement in the for loop and what it is
for.
Using find : )
You can instead use the find command like so:
find . -type f -iname 'CTCC_noSDS_*_hg19.bwt2pairs.validPairs' -exec bash -c 'cp {} mydir/' \;
Here is a safer/stricter find command using regex:
find . -regextype sed -regex ".*CTCC_noSDS_[0-9]\+_hg19.bwt2pairs.validPairs" -exec bash -c 'cp {} ./mydir/' \;
The shell did not ignore the variable. You are misusing variable expansion. Valid characters for variable names include underscores (one of which you have next to $i). So, what the shell is actually seeing is a variable called i__hg19, which is undefined. Thus, the filename is unexistent.
The solution is to wrap $i between curly braces like this:
cp ./CTCC_noSDS_0${i}_hg19.bwt2pairs.validPairs

how to move directories within a directory from a shell script?

trying a script to move folders from my internal to external hard disk from within a directory....
#!/bin/bash
for i in *; do
if [[ $i == [* ]]; then
mv $i /entertainment/movies/;
fi
done
i get the below error:
mv: cannot stat 'DVDRip': No such file or directory
mv: cannot stat '-': No such file or directory
mv: cannot stat 'x264': No such file or directory
mv: cannot stat '-': No such file or directory
mv: cannot stat 'DD5.1': No such file or directory
mv: cannot stat '-': No such file or directory
mv: cannot stat '1GB': No such file or directory
mv: cannot stat '-': No such file or directory
mv: cannot stat 'ESub': No such file or directory
Surround variable expansions with double quotes to ensure whitespace is handled properly.
mv "$i" /entertainment/movies/
The if test can be omitted if you only loop over files you're interested in.
for i in [*; do
mv $i /entertainment/movies/
done
And then you can even ditch the loop.
mv [* /entertainment/movies/

How to delete a file with a "Symbol for NULL" character (0x2400) in filename

ATTN: shell gods ;)
I can't seem to figure out how to delete a file with a unicode character 0x2400 in the filename on OSX (Example: ␀.test).
It's not a NULL character per-se, but a "symbol for null". (See: http://unicodelookup.com/#null/1)
Script - How to Reproduce
#!/usr/bin/env bash
dir="${HOME}/test_dir"
# Create Directory: ~/test_dir
if [ ! -d "${dir}" ]; then
printf "\nCreating Directory: ${dir}\n"
mkdir ${dir}
fi
# Create our character
char=$'\xE2\x90\x80'
# Create filename
file="${dir}/${char}.test"
# Create the File
printf "\nCreating File: ${file}\n"
touch ${file}
Delete the file... NOPE!
# Attempt 1 - Delete File
printf "\nDeleting File: ${file}\n"
rm -rf ${file}
Delete the whole directory... NOPE!
# Attempt 2 - Delete Directory
printf "\nDeleting Directory: ${file}\n"
rm -rf ${dir}
Delete the file via inode... NOPE!
# Attempt 3 - Delete File
inode=$(ls -i1 ${dir} | awk '{print $1}')
printf "\nDeleting via Inode: ${inode}\n"
find ${dir} -inum ${inode} -exec rm -i {} \;
The whole script should output something like this:
Creating File: /Users/bsmith/test_dir/␀.test
Deleting File: /Users/bsmith/test_dir/␀.test
rm: /Users/bsmith/test_dir/␀.test: Invalid argument
Deleting Directory: /Users/bsmith/test_dir/␀.test
rm: /Users/bsmith/test_dir/␀.test: Invalid argument
rm: /Users/bsmith/test_dir: Directory not empty
Deleting via Inode: 68592933
remove /Users/bsmith/test_dir/␀.test? y
rm: /Users/bsmith/test_dir/␀.test: Invalid argument
This command works for me:
rm ?.test
But sadly it is very probable that it will NOT work for you.
It is a known bug of osx:
Is it impossible to delete/move a file named “␀” on mac?
Rename folder with odd characters
The sure bet is to boot from a pen drive with some Linux OS, mount the file system in such Linux, and erase the file. It is sure that files with such names could be erased in Linux.

Bash, grep sentence from file

I have made a simple answering machine in bash. Basically if you greet it, it will greet you back but now I have a problem with sentence analyzing.
If the sentence ($#) is more than one word, it fails.
if [[ "$#" = $(grep -Fx "$#" 'vocabulary/greeting') ]]
then
speak greeting
elif [[ "$#" = $(grep -Fx "$#" 'vocabulary/appreciative') ]]
The output:
> hello
Sam: Hi!
> how are you
grep: are: No such file or directory
grep: you: No such file or directory
grep: are: No such file or directory
grep: you: No such file or directory
grep: are: No such file or directory
grep: you: No such file or directory
grep: are: No such file or directory
grep: you: No such file or directory
grep: are: No such file or directory
grep: you: No such file or directory
Sam: I don't understand.
>
How do I fix this?
How can I catch possible errors like these in the future?
Use "$*" instead of "$#".
if [[ "$*" = "$(grep -Fx "$*" 'vocabulary/greeting')" ]]
"$*" is a string representation of the arguments, while "$#" is an array.

check multiple files existing in a directory or not

I am new to UNIX, please help.
I have a file which has many lines, each line is a filename.
Now I want to check if each file exists in another directory with some prefixes.
For example, my text file content is
abc.def.ghi.jkl
mno.pqr.stu.vwx
I want to test if each file exists in a directory, like
cd <search directory>
ls -ltr *abc.def.ghi.jkl*
If above result is false then throw an error.
Note: The file content is DYNAMIC and I am generating this file through another script.
Assuming your file is
$ cat myList
abc.def.ghi.jkl
mno.pqr.stu.vwx
A quick solution is
cat myList | xargs ls -ltr
If files are not found, the output of ls will complain to stdout with
ls: xxx: No such file or directory
IHTH
This is the expected Answer
`ls -l > temp.cat
for i in $(cat temp.txt)
do
ls -l *$i*
if [[ $? -eq 0 ]]
then
echo " File found"
else
echo " File not found for $i"
fi
done
rm -f temp.txt`
`

Resources