Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 从文件名中提取唯一id_Linux_Bash_Shell_Unix - Fatal编程技术网

Linux 从文件名中提取唯一id

Linux 从文件名中提取唯一id,linux,bash,shell,unix,Linux,Bash,Shell,Unix,我通过将文本文件放在子目录中来组织目录中的文本文件。子目录名是从原始文件名派生的。通过这种方式,很容易判断哪个文件属于其各自的文件夹。bashfor循环遍历所有txt文件并相应地创建文件夹。文本文件具有以下示例格式:xxxx-test\u文件1-aa1-a2.txt或xxxx-test\u文件1-aa1--2.txt。根据第一个示例,对于即将创建的文件夹的名称,唯一重要的两件事是xxxx和-aa1-a2(始终在末尾有一个6个字符的唯一id)。因此,新文件夹将命名为xxxx-aa1-a2。以下仅适

我通过将文本文件放在子目录中来组织目录中的文本文件。子目录名是从原始文件名派生的。通过这种方式,很容易判断哪个文件属于其各自的文件夹。bash
for循环
遍历所有txt文件并相应地创建文件夹。文本文件具有以下示例格式:
xxxx-test\u文件1-aa1-a2.txt
xxxx-test\u文件1-aa1--2.txt
。根据第一个示例,对于即将创建的文件夹的名称,唯一重要的两件事是
xxxx
-aa1-a2
(始终在末尾有一个6个字符的唯一id)。因此,新文件夹将命名为
xxxx-aa1-a2
。以下仅适用于提取某些文件的正确名称,并与其他文件断开

FILE_PATH="/my_files/"
for file in "$FILE_PATH"/*.txt; do
    tmp=${file#*-}; head=${file%-"$tmp"}
    mid=${tmp%-*}; tail=${tmp#"$mid"-}
    base="${head,,}-${tail,,}"
    dir=${base%.txt}
    mkdir -p "$dir"
    mv "$file" "$dir/$base"
done
${var#prefix}
扩展到移除前缀的var值,而
${var%suffix}
相应地使用后缀执行相同的替换。最后,
${var,,}
生成值的小写版本。然后,我们简单地从这些部分组合您想要的文件名结构

如果文件只有两个
-
xxxx-test_file-aaasw1
xxxx-test_file-bswb2u

|-- ./
|   |-- xxxx-aaasw1
|       |--xxxx-test_file-aaasw1.txt
|   |-- xxxx-bswb2u
        |--xxxx-test_file-bswb2u.txt.
但是,如果文件中有两个以上的文件,则它会中断:
xxxx-test\u file-caa-v3u
xxxx-test\u file-caa-v3-

|-- ./
|   |-- xxxx-v3u
|       |-- xxxx-test_file-caa-v3u.txt
|   |-- xxxx-
        |-- xxxx-test_file-caa-v3-.txt.

那么,你想把目录命名为“a-b”,其中a是第一个破折号之前的所有内容,b是最后一个破折号和第一个点之间的所有内容

touch xxxx-test_file-aaasw1
touch xxxx-test_file-bswb2u
touch xxxx-test_file-caa-v3u.txt
touch xxxx-test_file-caa-v3-.txt

for f in *
do
    head=$(cut -f1  -d'-' <<< "$f")
     mid=$(cut -f2  -d'-' <<< "$f")
    tail=$(cut -f3- -d'-' <<< "$f" | cut -f 1 -d .)
     ext=$(cut -f3- -d'-' <<< "$f" | cut -f 2- -d .)
    echo "[$head][$mid][$tail][$ext]"
    mkdir "${head}-${tail}"
    mv "${f}" "${head}-${tail}/${head}-${tail}.${ext}"
    echo "${mid}" > "${head}-${tail}"/title_info.txt
done

tree

还有其他几种方法,但我能想到的方法比这种简单但效率不高的方法更为隐晦。

只需更改
mid
赋值,使其始终在破折号后修剪六个字符,然后是点和扩展名

mid=${tmp%-??????.*};

xxxx是否总是4个字符长?@hoipolloi yes
xxxx
总是
4
字符长,并且结尾
bswb-u
唯一id是
6
字符长。前面的问题:让我们回答一下。很抱歉再次打扰您,但当文件有两个以上的
-
时,此操作失败。这是一个真实的示例
xx-Official\u linux\u facts\u 101\u-\u Advanced\u Mode-YSp8Z.txt
导致
xx-Advanced\u Mode-YSp8Z
而不是
xx-YSp8Z
@code\u Ed\u学生代码处理超过2个破折号。问题在于附加破折号的位置:尾部可能有2个破折号,中间可能有破折号。这两个破折号不兼容。重命名
\u-\ u
格式的中间破折号就足够了,但我不会指望它。(注意,在前面的评论中xxxx始终为4,tail始终为6,但并非所有示例都符合该模式。我的解决方案只要求中间没有破折号。某些场景需要手动处理;这听起来像其中之一。只需手动删除中间的破折号即可。:)您的解决方案仍然是最好的解决方案!
mid=${tmp%-??????.*};