awk и рекурсия

Задача, собственно, заключается в том, чтобы находить файлы с нужным расширением и перемещать их на 1 уровень выше... Покурив в интернете, получилось такое вот борзописание:
#!/bin/bash
for s in $( find . -name *.mp3 ) ;
        do
                set destination = $i | awk '{ n = split(s, fld, "\n")
                sizepath = fld[1]
                m = split(sizepath, nodes, "/")
                for( j = 1; j-1 < m; j++ )
                dir = dir nodes[j] "/"
                print(dir) }' ;
                echo $destiantion
        done
Чего то не вкурил ?
или я чего то не понял или зачем так сложно?
#!/bin/bash
for ITEM in $(find * -iname '*.mp3'); do mv "$ITEM" "$(dirname "$ITEM")/../$(basename "$ITEM")"; done
PGP 0x31361F01
arcanisrepo
Доброго дня !

arcanis
или я чего то не понял или зачем так сложно?
#!/bin/bash
for ITEM in $(find * -iname '*.mp3'); do mv "$ITEM" "$(dirname "$ITEM")/../$(basename "$ITEM")"; done
Спасибо, хорошее решение :) Только здесь надо определить переменную IFS иначе find будет "разделять" по пробелам
#!/bin/bash
IFS="
"
for ITEM in $(find * -iname '*.mp3'); do mv "$ITEM" "$(dirname "$ITEM")/../$(basename "$ITEM")"; done
Можно ли как-нибудь "возврат каретки" записать в определении переменной одной строкой, чтобы использовать прямо из терминала, или заменить find чем-нибудь другим ?
да, я с пробелами не тестил) На самом деле не знаю, я в find не такой большой спец

А вообще find позволяет тут же и команду выполнить:
find . -iname '*.mp3' -execdir mv {} ../{} \;
execdir - выполнить команду из субдиректории. Рекурсивно тоже работает без проблем. И красивше, и проще, и работает.
PGP 0x31361F01
arcanisrepo
arcanis, спасибо !
Продолжу мучать тему:

А какая принципиальная разница между командами mv и ln -s ?

Попробовал так:
#!/bin/bash
IFS="
"
for ITEM in $(find * -iname '*.mp3'); do ln -s "$ITEM" "$(dirname "$ITEM")/../$(basename "$ITEM")"; done

И получается, что ссылка создается не ожидаемого Track1.mp3 -> Soundtrack/Track1.mp3 а такого вида: Track1.mp3 -> film/Soundtrack/Track1.mp3 - то есть опять рекурсия: есть папка film, где и создаются ссылки, но нет папки film/film

Строка: for i in $( find . -name *.mp3 ) ; do ln -s $i $(dirname "$i")/../$(basename "$i") ; done

Дает такой же результат - в цели ссылки, после относительного адреса (точки) повторяет имя родительской папки.
???

UPD: Да, и в порядке полного идиотизма, так find . -name *.mp3 -execdir ln -s {} ../{} \; создаются ссылки на самих себя :(
это проблема в понимании работы команды ln. Ей по барабану на первый аргумент, что напишете, туда и будет ссылаться. А потом шелл будет удивляться на какой нибудь файл в корневой директории, навроде superproga -> ../../../../bin/superproga.
Правильный вариант, наверное, такой:
find * -type f -name '*.mp3' -execdir ln -sr {} -t ../ \;
я еще добавил проверку типа файла, чтобы не создавал симлинк на симлинк на...нувыпонели.
В общем там надо путь, на что ссылается, раскрывать каким угодно образом (в циклах for тоже самое)
PGP 0x31361F01
arcanisrepo
arcanis
find * -type f -name '*.mp3' -execdir ln -sr {} -t ../ \;

Спасибо. Отличное решение, равно как спасибо и за basename и dirname, но все-таки проблемка с рекурсией внутри адреса файла остается, например, если надо в каждой директории, где есть, например фотографии, оставить их список:
find . -name *.jpg -exec echo {} > $(dirname {})/list.txt \;
К сожаалению, такая конструкция создает только один list.txt - в корне рабочей директории. Беда в том, что оператор dirname воспринимает адрес файла слитно, не позволяя разделять вложения по '/'
kotnaton, пожалуйста, сформулируйте чётко – что вам требуется сделать?

находить файлы с нужным расширением и перемещать их на 1 уровень выше
Звучит несколько странно и рекурсивно само по себе – находим файлы, перемещаем их на уровень выше, потом снова находим, перемещаем ещё выше... Где тут смысл? Что требуется на самом деле?
kotnaton
К сожаалению, такая конструкция создает только один list.txt - в корне рабочей директории.
не совсем понял, что вы хотите, но у вас опять команда неправильная =) Надо так примерно:
find . -name '*.jpg' -execdir bash -c "echo {} >> list.txt" \;
PGP 0x31361F01
arcanisrepo
 
Зарегистрироваться или войдите чтобы оставить сообщение.