Извлечь часть имени файла?

waitиспользуется исключительно в родительском процессе для ожидания завершения дочернего процесса (и для доступа к его статусу выхода ).

Кроме того, ни один процесс не может перехватывать KILLсигнал (исходного вопроса, использованного KILLв качестве примера ).

Кроме того, "ожидание сигнала" - необычная вещь.поскольку сигналы являются асинхронными событиями, то есть вы не ждете их, а вместо этого устанавливаете обработчик сигналов (с помощью trapв оболочке ), который будет обрабатывать сигнал всякий раз, когда Он прибывает. Сигнал может поступить в любой момент во время выполнения сценария, и обработчик сигнала будет выполнен, когда это произойдет (нормальный ход программы временно приостановится на время обработки сигнала ).

Очевидно, вы могли бы сделать что-то вроде

trap 'quit=1' USR1

quit=0
while [ "$quit" -ne 1 ]; do
    printf 'Do "kill -USR1 %d" to exit this loop after the sleep\n' "$$"
    sleep 1
done

echo The USR1 signal has now been caught and handled

для выполнения своего рода цикла «ожидание поступления сигнала».

Здесь «ловушка» будет «ловить» сигнал USR1, «обработчик» установит quitв 1, и управление будет возвращено коду, который выйдет из цикла.

0
20.06.2021, 18:47
3 ответа

Не анализировать вывод ls(, см., например,. Почему *не *parse `ls`(и что делать вместо )?). Проблема, с которой вы сталкиваетесь, заключается в том, что ваша переменная цикла fileбудет принимать значения ваших имен файлов после того, как все они будут объединены в одну длинную строку, а затем разделены на пробелы (и после любого разделения -. ] вверх слово, которое оказалось шаблоном подстановки, было расширено ). Вы получите три итерации цикла для имени файла XXX XXXX XXX-6VwvOkZvzuI.description, например, по одной для значений XXX, XXXXи XXX-6VwvOkZvzuI.description.

Для перебора всех файлов, в именах которых есть тире, а затем суффикс имени файла .description, используйте

for name in *-*.description; do...; done

Чтобы выделить часть перед -в $name, используйте стандартное расширение параметра, которое удаляет все после первого -в строке:

prefix=${name%%-*}

Разница между использованием %%и %здесь заключается в том, что с %%удаляется самая длинная совпадающая хвостовая строка. Это имеет значение, если в имени содержится несколько символов -.

Ваша петля становится

for name in *-*.description; do
    prefix=${name%%-*}
done

Суффикс имени файла уже известен (.description), но вы можете получить часть имени файла от -до суффикса, используя

infix=${name#"$prefix"}
infix=${infix%.description}

Наконец, с таким скриптом, как

#!/bin/sh

suffix=.description

for name in *-*"$suffix"; do
    prefix=${name%%-*}
    infix=${name#"$prefix"}
    infix=${infix%.description}

    printf 'prefix="%s", infix="%s", suffix="%s"\n' \
        "$prefix" "$infix" "$suffix"
done

вы получите

$ ls
XXX XXXX XXX-6VwvOkZvzuI.description          XXX XXXX XXX-6VwvOkZvzuK.description
XXX XXXX XXX-6VwvOkZvzuJ.description          script
$./script
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuI", suffix=".description"
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuJ", suffix=".description"
prefix="XXX XXXX XXX", infix="-6VwvOkZvzuK", suffix=".description"
6
28.07.2021, 11:23

Редактировать

Я оставлю свой ответ, но добавлю предупреждение из ответа @Kusalananda :Не проанализируйте вывод ls(, см., например. Почему *не *parse `ls`(и что делать вместо )?).

Мой ответ

Вы можете направить вывод ls напрямую в sed и заменить только часть стоит перед дефисом(-):

ls *.d* | sed 's/\(.*\)-.*/\1/'

Я попробовал это с двумя файлами с именами:

XXX XXXX XXX-6VwvOkZvzuI (copy).description
XXX XXXX XYZ-6VwvOkZvzuI.description

и вывод:

XXX XXXX XXX
XXX XXXX XYZ

Команда sed работает следующим образом:

  • Я помню что-то между вышеперечисленным, используя \(и \), которые в этом case - все до последнего дефиса в имени файла (, которое вам нужно адаптируйте его, если ваши файлы имеют более поздние дефисы в именах)
  • Затем замените запомненным содержимым \1-, то есть только часть XXX

При необходимости вы можете поместить вывод команды в файл с помощью:

ls *.d* | sed 's/\(.*\)-.*/\1/' > new_file
0
28.07.2021, 11:23

Попробуйте это

$ ls -1
x.sh
XXX XXXX XXX-6VwvOkZvzuI.description
YYY XXXX XXX-6VwvOkZvzuI.description
$ cat x.sh
#!/bin/bash
for file in *.d*
do
 fname=${file/-*/}
 ext=${file/*-/}
 echo fname $fname ext $ext
done
$./x.sh
fname XXX XXXX XXX ext 6VwvOkZvzuI.description
fname YYY XXXX XXX ext 6VwvOkZvzuI.description
$
0
28.07.2021, 11:23

Теги

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