Bash loop - creating a folder for each existing tx

2019-08-02 15:26发布

问题:

I have text files in a directory that I want to organize. I am trying to do so thru bash by creating a directory for each file. As I move the file to its respective new folder, I want to modify the original filename and create an additional text file labeld info.txt that holds the original file name(this file is also place in the new folder). The files name change goes from xxx-file_name-aa1.txt to xxx-aa1.txt. Anything between the first and last - is stripped out. The folder has the same name as the file xxx-aa1.

test.sh (my sed statement strips whitspaces and turns everything to lower case except anything after the last -

FILE_PATH="/media/sf_linux_sandbox/txt_files/"
while read -r file; do
#sed statement empty
new_name=$(echo "$file" | sed 's/^\(.*\)\(-[^-]*\)$/\L\1\E\2/; s/ *- */-/; s/^\(.*\) \+- *\([^-]*\)$/\1-\2/; s/ /_/g')
mv "$file" "$new_name"
done < <(find $FILE_PATH -maxdepth 1 -type f -name '*.txt')

Input:

|-- ./
|   |-- xxxx-test_file1-aa1.txt
|   |-- xxxx-test_file2-bb2.txt

Desired Output:

|-- ./
|   |-- xxxx-aa1
|       |--xxx-aa1.txt
|       |--info.txt // contains name 'test_file1'
|   |-- xxxx-bb2
        |--xxx-bb2.txt
        |--info.txt // contains name 'test_file2'

Current Output

|-- ./
|   |-- xxxx-test_file-aa1
|       |--xxxx-test_file-aa1.txt
|   |-- xxxx-test_file-bb2
        |--xxxx-test_file-bb2.txt

回答1:

You can actually do all these manipulations in Bash itself.

Since you have -maxdepth 1 it looks like you can just use a wildcard loop instead of find so I refactored that, too.

FILE_PATH="/media/sf_linux_sandbox/videos/"
for file in "$FILE_PATH"/*.mp4; do
    tmp=${file#*-}; head=${file%-"$tmp"}
    mid=${tmp%-*}; tail=${tmp#"$mid"-}
    base="${head,,}-${tail,,}"
    dir=${base%.mp4}
    mkdir -p "$dir"
    mv "$file" "$dir/$base"
    echo "$mid" >"$dir"/info.txt
done

Briefly, ${var#prefix} expands to the value of var with prefix removed, and ${var%suffix} correspondingly performs the same substitution with a suffix. Finally, ${var,,} produces the lowercase version of the value. Then we simply assemble the file name structure you want from those parts.



回答2:

change the sed as

new_name=$(echo "$file" | sed -r 's/-[^-]*-/-/g')

eg:

$ echo xxxx-test_file-aa1.txt | sed -r 's/-[^-]*-/-/g'
xxxx-aa1.txt

-[^-]*- selects the string between two - , sed s replace it with -

Also you can use grep command to get the name of the directory as

$ echo $new_name | grep -o '^[^.]*'
xxxx-aa1

^[^.]* selects the portion in filename, that doesnt contain . that is ommits the extension.

EDIT

To get the name of the file

$ echo "xxx-test_file-aa1.txt" | grep -oP '(?<=-)[^.]*(?=-)'
test_file

(?<=-) lookbehind assertion checks if the pattern is preseced by -

(?=-) lookahead assertion checks if the pattern is followed by -

[^.]* pattern matches anything other than ., selects the filename