#bash #ubuntu #grep #line-endings
#bash #ubuntu #grep #окончания строк
Вопрос:
Я пытаюсь создать каталог из переменной, которая поступает из grep-ing, и он продолжает давать сбой, сообщая мне, что возврат каретки есть там, где его нет. Я пробовал dos2unix, он сообщает мне, что это недопустимый файл. Я создал скрипт в ubuntu 10.10 с использованием окончаний строк gedit и unix.
Я также попытался передать вывод файла cat’d в
tr -d 'r'
это не поможет.
вот часть скрипта, в которой произошел сбой:
ARTIST=`cat read | grep DTITLE | cut -c8- | cut -d"/" -f 1`
ALBUM=`cat read | grep DTITLE | cut -c8- | cut -d"/" -f 2 | awk '{gsub(/^[ t] |[t] $/,"")};1'`
mkdir $DEST/"$ARTIST"
cd $DEST/"$ARTIST"
mkdir "$ALBUM"
mv $DEST/temp/*.flac $DEST/"$ARTIST"/"$ALBUM"/
и ошибка, которую я получаю:
mv: target `Hardr' is not a directory
вот файл «read», из которого он извлекается:
macmini:~/Dropbox/bin$ cat ~/Desktop/temp/read
210 folk 0d021f02 CD database entry follows (until terminating `.')
# xmcd CD database file
#
# Track frame offsets:
# 150
# 13002
#
# Disc length: 545 seconds
#
# Revision: 0
# Processed by: cddbd v1.5.2PL0 Copyright (c) Steve Scherf et al.
# Submitted via: CDex 1.50Beta7
#
DISCID=0d021f02
DTITLE=Cursive / Art is Hard
DYEAR=2003
DGENRE=Indie
TTITLE0=Art is Hard
TTITLE1=Sinner's Serenade
EXTD= YEAR: 2003
EXTT0=
EXTT1=
PLAYORDER=
.
на этом этапе я немного заблудился. откуда берется возврат каретки?
Комментарии:
1. Вы уверены, что версия запущенного вами скрипта соответствует той, которую вы опубликовали? Сообщение об ошибке выглядит так, как будто оно исходит из скрипта без двойных кавычек
$ALBUM
в аргументеmv
.
Ответ №1:
Я думаю, что это происходит из прочитанного файла. Запустите dos2unix
этот файл.
Однако это сообщение об ошибке подчеркивает другую проблему: mv
неверно интерпретирует то, что вы ему даете, потому что то, что он считает целевым, слишком короткое. Я предполагаю, что вы неправильно указываете пути к файлам, содержащие пробелы. Попробуйте заключить весь аргумент в двойные кавычки, а не только его компоненты.
Комментарии:
1. Да, всегда нужно заключать переменные имени файла в двойные кавычки в bash. Распространенная ошибка.
2. Если скрипт был запущен, как показано, это не проблема.
$DEST/"$ARTIST"/"$ALBUM"/
точно так же, как$DEST"/$ARTIST/$ALBUM/"
или как"$DEST/$ARTIST/$ALBUM/"
, если в$DEST
нет никаких специальных символов. Сообщение об ошибке показывает, что$ALBUM
было разделено и после него не было/
.3. ах, это имеет больше смысла. я пытался разделить «исполнитель / альбом» на отдельные переменные для обоих, используя cut. я думал, что это то, что вырезает -d»/» -f 2 и cut -d»/» -f 1, вырезает все до, а затем все после «/»
4. я собираюсь отметить это как ответ, поскольку запуск dos2unix в этом файле решил проблему. не так элегантно, как хотелось бы, но я не знаю, как / почему в этом файле есть возврат каретки, так что это сработает. если у кого-нибудь есть какие-либо идеи, почему у него это есть, пожалуйста, дайте мне знать.
5. у кого-нибудь есть идеи, почему это вставляет возврат каретки? я бы хотел удалить зависимость от dos2unix.
Ответ №2:
Вы можете сделать это с помощью одного awk-скрипта
#!/bin/bash
awk -F"[/=]" 'BEGIN{
qq="47"
DEST="/tmp"
}/DTITLE/{
ARTIST=$2
ALBUM=$NF
gsub(/^[ t] |[ t] $/,"",ALBUM)
gsub(/^[ t] |[ t] $/,"",ARTIST)
cmd="mkdir "qq DEST"/"ARTIST qq
print cmd
#system(cmd)
cmd="mkdir -p " qq DEST"/"ARTIST "/" ALBUM qq
print cmd
#system(cmd)
cmd="mv "DEST"/temp/*.flac " qq DEST"/"ARTIST "/" ALBUM qq
print cmd
#system(cmd)
} ' file
Чтобы запустить его, сохраните как сценарий оболочки (например myscript.sh ) и введите ./myscript.sh
в командной строке
Или вы можете использовать язык программирования, который решает проблемы с громоздкими кавычками оболочки, например, скрипт Ruby (1.9 )
#!/usr/bin/env ruby
require 'fileutils'
DEST="/tmp"
File.open("file") do |f|
while not f.eof?
line = f.gets.chomp
if line[/DTITLE/]
line = line.split(/[/=]/)
ARTIST=line[1].strip
ALBUM=line[2].strip
Dir.mkdir( File.join(DEST, ARTIST) )
Dir.mkdir( File.join(DEST, ARTIST, ALBUM) )
Dir.glob( File.join(DEST, "temp", "*.flac") ).each do |file|
FileUtils.mv ( file, File.join(DEST, ARTIST, ALBUM) )
end
end
end
end
Чтобы запустить его, сохраните как (например, myscript.rb ) и введите ruby myscript.rb
в командной строке или внутри сценария оболочки.
Комментарии:
1. вау, это здорово. не могу дождаться, чтобы попробовать это сегодня вечером. возможно, это глупый вопрос, но есть ли способ использовать 2 разных интерпретатора в одном скрипте? я полагаю, что нет, так что я должен вызвать это из другого скрипта или я должен переписать это на ruby?
2. Вы бы использовали оболочку для выполнения скриптов. Если вы хотите использовать
awk
решение, просто скопируйте и вставьте и сохраните его как сценарий оболочки и запустите в обычном режиме. Если вы решите использовать Ruby, то используйте интерпретатор ruby для запуска скрипта. например, введитеruby myscript.rb
в командной строке.