Назад | Перейти на главную страницу

AWK и имена файлов с пробелами.

Я пытаюсь разобрать файлы с помощью 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))}'

Я получаю весь результат

Файл с пробелами 2

Здесь 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.

Я надеюсь, что это помогает. Более того, если вы присваиваете это значение переменной в скрипте, вам необходимо заключить переменные в двойные кавычки. В противном случае вы получите ошибки, если будете выполнять какую-либо другую операцию с именем извлеченного файла.