Bash循环 - 为目录中的每个现有txt文件创建一个文件夹

时间:2014-10-24 03:16:35

标签: linux bash shell unix

我在要组织的目录中有文本文件。我试图通过为每个文件创建一个目录来通过bash这样做。当我将文件移动到其各自的新文件夹时,我想修改原始filename并创建一个标记为info.txt的附加文本文件,其中包含原始文件名(此文件也放在新文件夹中) )。文件名称更改从xxx-file_name-aa1.txt变为xxx-aa1.txt。第一个和最后一个-之间的任何内容都被删除了。该文件夹与文件xxx-aa1具有相同的名称。

test.sh(我的sed语句删除whitspace并将所有内容转换为小写,除了上一个-之后的任何内容

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')

输入:

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

期望的输出:

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

当前输出

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

2 个答案:

答案 0 :(得分:2)

你实际上可以在Bash中进行所有这些操作。

由于您有-maxdepth 1,看起来您可以使用通配符循环而不是find,所以我也重构了它。

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

简单地说,${var#prefix}扩展为var的值,prefix被删除,而${var%suffix}相应地使用后缀执行相同的替换。最后,${var,,}生成值的小写版本。然后我们简单地从这些部分组装你想要的文件名结构。

答案 1 :(得分:1)

sed更改为

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

例如:

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

-[^-]*-选择两个-之间的字符串,sed s将其替换为-

此外,您可以使用grep命令将目录名称设为

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

^[^.]*选择文件名中的部分,该部分不包含.,省略了扩展名。

修改

获取文件名称

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

(?<=-) lookbehind断言检查模式是否由-预先设置

(?=-)前瞻断言检查模式是否后跟-

[^.]*模式匹配.以外的任何模式,选择文件名