简体   繁体   中英

How to concat “/” delimiter to string?

Task: concatinate array of string with delimiter, dilimeter is "/".

Metatask: i've a folder with many files. Need to copy them into another folder. So i need to get "name of file" and "path to folder".

What's wrong: delimiter "/" works incorrectly. It doesn't concatinate with my strings. If i try to use "\\/" - string disappeare at all.

What's going on?

loc_path='./test/*'

delim='\/'

for itt in $loc_path; do
    IFS=$delim
    read -ra res <<< "$itt"
    str=''
    for ((i = 1; i \<= ${#res[@]}; i++)); do
        #str=($str${res[$i]}$delim)
        str="$str${res[$i]}$delim"
    done
    echo $str
done

Please, give to two answers:

  1. how to solve task-problem
  2. better way to solve metatask

There is an issue in delim='\\/'. Firstly, you need not to protect slash. Secondly all characters are already protected between simple quotes.

There is a syntax issue with your concatenation. You must not use parenthesis here! They can be used to open a sub shell. We need not that.

To solve your 'meta-task', you should avoid to use IFS, or read. They are complex to use (for example by modifying IFS globally as you do, you change how echo display the res array. It can mislead you while you troubleshoot...) I suggest you use more simple tool like: basename, etc.

Here few scripts to solve your meta (scholar?) task:

# one line :-)
cp src/* dst/


# to illustrate basename etc
for file in "$SRC/"*; do
    dest="$DST/$(basename $file)"
    cp "$file" "$dest"
done

# with a change of directory
cd "$SRC"
for file in *; do cp "$file" "$DST/$file"; done
cd -

# Change of directory and a sub shell
(cd "$SRC" ; for file in *; do cp "$file" "$DST/$file"; done)

Task solution:

arr=( string1 string2 string3 )            # array of strings
str=$( IFS='/'; printf '%s' "${arr[*]}" )  # concatenated with / as delimiter

$str will be the single string string1/string2/string3 .

Meta task solution:

Few files:

cp path/to/source/folder/* path/to/dest/folder

Note that * matches any type of file and that it does not match hidden names. For hidden names, use shopt -s dotglob in bash . This will fail if there are thousands of files (argument list too long).

Few or many files files, only non-directories:

for pathaname in path/to/source/folder/*; do
    [ ! -type d "$pathame" ] && cp "$pathname" path/to/dest/folder
done

or, with find ,

find path/to/source/folder -maxdepth 1 ! -type d -exec cp {} path/to/dest/folder \;

The difference between these two is that the shell loop will refuse to copy symbolic links that resolve to directories, while the find command will copy them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM