如何提取 SubDir 名称 4 深度并放入 Var 4 中稍后使用?

如何提取 SubDir 名称 4 深度并放入 Var 4 中稍后使用?

我需要知道如何将第四个目录名称放入树中。这个目录 var 在使用循环进行操作时会发生变化,因此当循环运行时总是更新这个目录结构体,我需要更新它并保持它是最新的

/dir 1/dir 2/dir 3/dir 4/dir 5/ 我只需要将第四个目录中的名称放入 var 中即可在其他地方使用它

我正在使用这样的循环和提取。

#!/bin/bash

working_dir="/media/data/temp1"

script_dir="$HOME/working"

find "$working_dir" -type f -name "*.*" | while [ $xf  -lt $numberToConvert ] ; 
do read FILENAME;

j=$FILENAME
xpath=${j%/*} 
xbase=${j##*/}
xfext=${xbase##*.}
xpref=${xbase%.*}
path1=${xpath}

pref1=${xpref}
ext1=${xfext}
echo 
echo
echo "xpath is -> "$xpath""
echo "xbase is -> "xbase""
echo "xfext is -> "$xfext""
echo "xpref is -> "$xpref""
echo "path is -> "$path1""
echo "pref is -> "$pref1""
echo "ext is -> "$ext1""
echo
getme="$(basename "$working_dir/")" 
echo "GET ME "$getme""
echo

  //Code that does stuff to files in dir's after the 4th Dir
  // is here but hidden 

let xf++
done

所有这些的输出是:

xpath is -> /media/data/temp1/Joe Jackson - The Ultimate Collection/CD2
xbase is -> xbase
xfext is -> mp3
xpref is -> Jumpin' Jive Live - Joe Jackson
path is -> /media/data/temp1/Joe Jackson - The Ultimate Collection/CD2
pref is -> Jumpin' Jive Live - Joe Jackson
ext is -> mp3

GET ME temp1

basename 返回第三个目录,而不是该目录之后的第四个目录,这就是我需要获取 /temp1/ ... / 和 CD 之间的目录的名称

/media/data/temp1/Joe Jackson - The Ultimate Collection/CD2

当脚本完成后,乔·杰克逊...目录名称将会更改,进入另一个具有不同名称的第四个目录,因此我需要能够更新它并保持当前仅获取第四个目录名称。

我所需要的只是像这样的线

    4thDirNameIs=${code goes here}

它是目录结构的 4 层,而不是 5 或 3 或任何其他目录或文件名。

该标题告诉了一切,进入是关键字,必须位于目录之外才能进入目录的第四个目录名称。

我希望这次已经足够清楚了

答案1

如果你的文件保存为$FILENAME,这些都会给你第四个目录。在这些示例中,我手动设置

FILENAME="/media/data/temp1/Joe Jackson - The Ultimate Collection/CD2/Jumpin' Jive Live - Joe Jackson.mp3"
  • 使用外壳:

    $ dir=${FILENAME#*/*/*/*/}; echo ${dir//\/*}
    Joe Jackson - The Ultimate Collection
    

    在这里,我首先删除前 4 个斜杠,保留第四个目录和文件名,然后删除文件名。

  • 外壳和basename

    $ dir=${FILENAME#*/*/*/*/}; basename "$dir"
    Jumpin' Jive Live - Joe Jackson.mp3
    

    与上面的想法实际上相同,只是用于basename最后一步。

  • 用 Perl 解析它:

    $ 回显“$FILENAME”| perl -pe 的#(.?/){4}(.?)/.*#$2#' 乔·杰克逊 - 终极精选

    正则表达式匹配 4 次重复的 0 个或多个字符,后跟斜杠,然后是下一个斜杠的所有内容,然后是其他所有内容。括号可以让您捕获匹配的模式,因此我们用第二个模式(目录名称)替换所有内容。

    或者,您可以将行拆分为 slasehs 上的数组并打印第 5 个字段(第 5 个字段是因为/变量开头的 导致第 1 个字段为空):

    $ echo "$FILENAME" | perl -F"/" -lane 'print $F[4]'
    Joe Jackson - The Ultimate Collection
    
  • 解析它awk

    $ echo "$FILENAME" | awk -F"/" '{print $5}'
    Joe Jackson - The Ultimate Collection
    

    同样的想法,但是在awk.

答案2

您可以尝试使用 mindepth 和 maxdepth 参数进行 find 并将其通过管道传输到 awk。

find $someBaseDir -type d -mindepth 4 -maxdepth 4 | awk -F'/' '{ print $NF }'

如果您想对每个结果执行某些操作,可以将其放入 for 循环中:

也许是这样的:

for fdir in $(find $Base -type d -mindepth 4 -maxdepth 4 | awk -F'/' '{ print $NF }'); do DO_STUFF_WITH $fdir done

答案3

Jong 的答案非常接近,但mindepthmaxdepth参数是相对于命令的起始目录的find。您还可以考虑这样一个事实:您已经拥有所需目录结构的前三个部分。从那时起,你真的只需要走更深入地获取您正在寻找的信息。这样做的额外好处是排除目录中的其他所有内容除了为了你想要的东西。以下代码片段使用预定义的变量$working_dir-mindepth-maxdepth参数find以及参数扩展来查找 /media/data/temp1 中“4 深”位置的每个目录:

for my_dir in $(find ${working_dir} -mindepth 1 -maxdepth 1 -type d -print)
    do
    DirName=${my_dir##${working_dir}/}
    ## loop through, working on the 4th directory list
    ## one directory at a time
    . . .
done

FWIW,你不应该以数字开头变量名。某些 shell(如 BASH)会将它们插入为位置参数的引用,并且不会执行您期望的操作(例如,$4thDirNameIs将扩展为位置参数$4,该参数可能存在也可能不存在,后跟“thDirNameIs”)。

答案4

感谢这个问题中帮助我的每个人,这是我想出的答案,它找到根目录/文件夹中第四个目录的所有目录,然后一次进入一个目录获取所有文件并继续工作它们位于最内层循环中。所有选定的文件完成后,它会移动到下一个 basedir 的第四个位置,然后它的子目录也会执行相同的操作

由用户输入控制他想要让它在多少个目录上工作以及在哪里工作

#!/bin/bash

typeset -i f d control DirCountDn fileCount dirCount
let f=0 d=0 control=1  DirCountDn=0 fileCount=0 dirCount=0

amount_of_dir_to_work_on="4"

working_dir="/media/data/music"


   #CONTROL LOOP keeps it one dir at a time
        for i in 1
        do
            # get all of the names of the base dir to change name  a var containing ampunt of basenamedir in last place here 
            find "$working_dir" -mindepth 1 -maxdepth 1 -type d | while [ $DirCountDn  -lt $amount_of_dir_to_work_on ] ; 
                do read DIRNAME;
                    echo "$DIRNAME"
                    echo
                    MAXMP3="$(find "$DIRNAME" -type f -name "*.mp3" | wc -l)"
                    echo;echo;echo
                    echo "amount of mp3 "$MAXMP3" in "$DIRNAME""
                    echo;echo;echo;echo
                        find "$DIRNAME" -type f -name "*.mp3" | while [ $fileCount -lt $MAXMP3 ] ;
                        do read FILENAME;
                            echo;echo
                            echo "***************************************"
                            echo "FILENAME is "$FILENAME""
                            DIRNAME=${DIRNAME#*/*/*/*/} 
                            DIRNAME=${DIRNAME//\/*}
                            echo "DIRNAME is "$DIRNAME""
                            echo
                            echo " work each mp3 file in incurments until Dir is finised will all mp3 files" 
                            echo "rename dir then make provisons to move it somewhere else"
                            echo "then move it - go onto nest directory within the tree root dir"
                            echo "amount of filename "$fileCount""
                            echo "******************************************"
                            let fileCount++
                            echo "count on file names "$fileCount""
                            echo;echo

                        done
                let dirCount++
                echo "Dir Count "$dirCount""
                echo;echo
                let DirCountDn++

                #reset fileCount for next dir
                let fileCount=0
                done

                echo "this is i -> "$i""
        done

 # returns sub dir only one deep and not working dir
#find /dir/dir/dir/getThisOneNameOnly  -mindepth 1 -maxdepth 1  -type d   -exec basename {} \;

相关内容