Разделение путей к каталогам для получения имен файлов

Сначала удалите файлы, затем пустые каталоги:

find . -type f -exec rm \{\} \;
find . -depth -type d -empty -exec rmdir \{\} \;
6
25.10.2014, 07:07
5 ответов

При обращении к $ C Если на файл Вы имеете в виду полный путь к файлу, то это задание действительно очень легко. Есть несколько способов сделать это.

Используя только POSIX Shell Globs и расширение параметров, вы можете сделать:

c='/home/user/working-root-directory/band-folder/album-name/music-file.mp3'
file=${c##*/}
album=${c#*"${c%/*/"$file"}"/}
band=${c#*"${c%/*/"$album"}"/}
band=${band%%/*} album=${album%%/*}

в основном это работает, обрезая строку из хвоста переменной, а затем обрезающая результаты из головки переменной. В последней строке любые нежелательные останки от хвоста отдаются. Возможно, легче понять с реальными мировыми данными. Если вы должны были обернуть вышеупомянутый фрагмент в оболочке с помощью SET -X включен, вы увидите что-то вдоль этих строк, напечатанные в STDERR :

+ c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3
+ file=music-file.mp3
+ album=album-name/music-file.mp3
+ band=band-folder/album-name/music-file.mp3
+ band=band-folder
+ album=album-name

другой способ сделать это Состоит в том, чтобы использовать внутренний сепаратор полевой сепараторы Shell, чтобы разделить путь на / границ.

set -f; IFS=/             #disable globbing so as not to gen more filenames
set -- $c                 #set the shell's arg array to split path
shift "$(($#-3))"         #remove all but relevant fields
band=$1 album=$2 file=$3  #assign values

Вот еще немного Set -x Выход:

+ c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3
+ set -f
+ IFS=/
+ set -- '' home user working-root-directory band-folder album-name music-file.mp3
+ shift 4
+ band=band-folder
+ album=album-name
+ file=music-file.mp3
8
27.01.2020, 20:22

Предыдущие решения кажутся чрезмерно сложными для меня. Мне кажется, что следующее - это самое простое решение.

Чтобы получить имя каталога строк файла в Bash

 dirname "$varcontainingfilename"

, чтобы получить единственное имя файла из строки имени файла в использовании Bash

 basename "$varcontainingfilename"

с этой базы, которую вы должны легко делать то, что вы хотите.

Пример, выполняющий этот скрипт оболочки в виде скрипта / A / B / C, будет служить в качестве примера

 #!/bin/sh
 set -u
 PATH='/bin:/usr/bin'
 export PATH
 filestring="$1"
 fn=`basename "$filestring"`
 dn=`dirname "$filestring"`
 echo Original File String "$filestring"
 echo Filename is "$fn"
 echo directory is "$dn"
 exit 0
2
27.01.2020, 20:22

Чтобы сделать «играть» с переменными чуть более короткими

c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3
for var in file album band 
do
  eval "$var=\${c##*/}"
  c=${c%\/${!var}}
done

echo $file $album $band
music-file.mp3 album-name band-folder

другим способом - использовать Команда

IFS=/ read -r band album file  <<< ${c#"${c%/*/*/*}"/}
2
27.01.2020, 20:22

Я бы найма ZSH ZSH для этой работы:

$ c='/home/user/working-root-directory/band-folder/album-name/filename.mp3'

$ echo $c:h
/home/user/working-root-directory/band-folder/album-name
$ echo $c:h:h
/home/user/working-root-directory/band-folder
$ echo $c:h:h:h
/home/user/working-root-directory

(...)

$ echo $c:t    
filename.mp3
$ echo $c:h:t
album-name
$ echo $c:h:h:t
band-folder

(...)

Если вам нужно использовать жизнь Bash сложнее, вам нужно использовать временные переменные:

$ c='/home/user/working-root-directory/band-folder/album-name/filename.mp3'

$ x1=${c%/*}
$ echo $x1
/home/user/working-root-directory/band-folder/album-name
$ x2=${x1%/*}
$ echo $x2
/home/user/working-root-directory/band-folder

 (...)

$ y1=${c##*/}
$ echo $y1
filename.mp3
$ y2=${x1##*/}
$ echo $y2
album-name
$ y3=${x2##*/}
$ echo $y3
band-folder

(...)
2
27.01.2020, 20:22

Вы могли бы использовать SED , как это:

    sed 'h;s/,[^|]*//g;x
    /,/{s/|[^,|]*,*/|-/g;H;}
    x;s/-\([^|]\)/\1/g;P;D'

Это ранило относительно проще в конце концов. Применяя этот маленький скрипт к вашим данным:

key1|0|11881|0|0|0|0|11769|0|0|0
key2|2027|345|0|1|0|2040|364|0|1|0
key2|-|712|-|-|-|-|729|-|-|-
key3|0|670944|0|0|0|0|495554|0|0|0
key4|1847|1|0|0|0|1814|1|0|0|0
key4|-|21|-|-|-|-|22|-|-|-
key5|1880|11|0|154|0|1886|11|0|151|0
key5|-|402|-|-|-|-|397|-|-|-
key6|1|65|0|8|0|16684|51|0|8|0
key6|1|4570|-|-|-|0|4176|-|-|-
key6|19137|-|-|-|-|-|-|-|-|-
key7|1851|11|0|202|0|1856|13|0|193|0
key7|-|757|-|-|-|-|751|-|-|-

в основном SED просто решает каждое поле с обоих концов. Сначала он сохраняет копию своей текущей итерации в H старого пространства. Затем SED удаляет все, от каждого поля после первой запятой. После этого SED выключается обратно к сохраненной копии, поэтому он может удалить поле, которое он просто сохранен в другом буфере.

Если запятыми остаются, добавляет вторую копию к первому следующему вставленным \ N символ EWLINE, так что он может резать как минимум еще раз, когда P; D P Rint Затем D D Elete только до первого происхождения \ N символ EWLine в области шаблона, прежде чем начать с тем, что остается.

-121--105607-

ZSH - это гораздо более элегантное решение , но если это не ваша оболочка, вы можете использовать awk :

 printf "%s\n" "$path"
/home/user/working-root-directory/band-folder/album-name/music-file.mp3

band=$(awk -F/ '{print $(NF-2)}' <(printf "%s" "$path"))
printf "%s\n" "$band"
band-folder

album=$(awk -F/ '{print $(NF-1)}' <(printf "%s" "$path"))
printf "%s\n" "$album"
album-name

file=$(awk -F/ '{print $NF}' <(printf "%s" "$path"))
printf "%s\n" "$file"
music-file.mp3
1
27.01.2020, 20:22

Теги

Похожие вопросы