Я пытаюсь разобрать файлы с помощью awk, чтобы изменить их имена. Все шло хорошо, пока я не начал делать это с файлами с пробелом в имени файла. Имена файлов похожи на 11237_712312955_2012-01-04 18_31_03.wav
и я хочу заменить wav из имени файла. Это пример моего кода:
ls | awk -F\. '{print $1}'
После того, как я запустил это в консоли, все в порядке, и я получаю имя файла без расширения.
Пример: файл 11237_712312955_2012-01-04 18_31_03.wav
после ls | awk -F\. '{print $1}'
в консоли я получаю:
11237_712312955_2012-01-04 18_31_03
и это правильно.
Но когда я вставляю это в свой сценарий:
#!/bin/bash
for i in $(ls);
do
FILENAME=echo $i | awk -F\. '{print $1}'
; #problematic line
echo $FILENAME
done
Скрипт разделяет файл на два в том месте, где есть пробел.
Вывод из скрипта:
11237_712312955_2012-01-04
18_31_03
Как заставить мой скрипт работать правильно?
Проблема здесь в разборе с ls
. Рассмотрите возможность взглянуть здесь: Почему не следует анализировать вывод ls.
Причина, по которой вы не должны этого делать, заключается в том, что UNIX допускает практически любой символ в имени файла, включая пробелы, символы новой строки, запятые, символы вертикальной черты и многое другое, что вы когда-либо пытались использовать в качестве разделителя, кроме NUL. В режиме по умолчанию, если стандартный вывод не является терминалом, ls
разделяет имена файлов символами новой строки. Это нормально, пока у вас нет файла с новой строкой в имени.
Боже мой, это ужасно.
Ваш скрипт использует bash; Я предлагаю вам сделать это вместо этого:
#!/bin/bash
for i in *.wav; do mv "${i}" "${i%.wav}.ext"; done
Увидеть Руководство по Bash для получения дополнительных сведений о расширении параметров.
Вы можете попробовать это.
awk '{print substr($0, index($0,$9))}'
Например, это результат выполнения команды ls:
-rw-r - r--. 1 корень root 73834496 6 дек 10:55 Файл с пробелами 2
Если вы используете простой awk вроде этого
# awk '{print $9}'
Возвращает только
# File
Если используется с полной командой
# awk '{print substr($0, index($0,$9))}'
Я получаю весь результат
Здесь substr (s, a, b): возвращает b количество символов из строки s, начиная с позиции a. Параметр b необязательный.
Например, если совпадение - это адрес 192.168.1.133 и вы используете substr следующим образом
# awk '{print substr($2,6)}'
Вы получаете IP-адрес 192.168.1.133. Обратите внимание, что 6 - это символ, начинающийся с in addr
Итак, в правильной команде $ 2 равно $ 0 (которая печатает всю строку), а index ($ 0, $ 9) соответствует $ 9 и печатает все перед столбцом 9. Вы можете изменить это на index ($ 0, $ 8) и увидеть, что результат изменится. к
# 10:55 File with spaces 2
index (IN, FIND). Выполняет поиск в строке IN первого вхождения строки FIND и возвращает позицию в символах, с которой это вхождение начинается в строке IN.
Я надеюсь, что это помогает. Более того, если вы присваиваете это значение переменной в скрипте, вам необходимо заключить переменные в двойные кавычки. В противном случае вы получите ошибки, если будете выполнять какую-либо другую операцию с именем извлеченного файла.