Я нашел что-то в сценарии, но не принадлежал к основному сценарию. Там было :> в строке.
Не могли бы вы объяснить мне, что это значит?
:> file
while read A B C D E; do echo "$A;$B;$D;$E;$C" >> file; done < otherfile
Я нашел что-то в сценарии, но не принадлежал к основному сценарию. Там было :> в строке.
Не могли бы вы объяснить мне, что это значит?
:> file
while read A B C D E; do echo "$A;$B;$D;$E;$C" >> file; done < otherfile
:> file
Это краткий способ сказать:
file не существует, создайте его, иначе обрежьте его до 0 байтов.Это означает, что вы можете быть уверены, что file существует и он пуст.
Вы также можете использовать > file но :> file является более переносимым.
См. Вопрос переполнения стека. Какова цель GNU Bash Builtin? для дополнительной информации.
Это похоже на причудливый способ создания нового файла. В bash : пустая команда:
$ type :
: is a shell builtin
$ help :
:: :
Null command.
No effect; the command does nothing.
Exit Status:
Always succeeds.
> перенаправляет вывод : в файл.
: другое имя для true . Оба являются встроенными в bash, но нет /bin/: только a /bin/true . Перенаправление вывода заставляет оболочку open(2) файл с помощью O_CREAT|O_TRUNC . Если ничего не написано, оно остается на нулевой длине.
Собрав воедино эти две части, :> file - довольно распространенная идиома для усечения файлов. Большинство людей пытаются сделать его менее странным, написав : >file .
Поскольку вы спросили в комментарии о второй строке, я превращу свои комментарии в ответ. (даже если вы не задавали это в своем вопросе.)
Вторая строка представляет собой цикл, который читает строки из otherfile в некоторые именованные переменные. Тело цикла использует echo для их печати ; разделители вместо пробелов, которые у них были раньше. file закрывается и повторно открывается (для добавления) каждую итерацию, потому что перенаправление находится внутри цикла. Использование while ...;do read -r ...;done <otherfile >file будет меньше отстой и избавит от необходимости сначала обрезать файл. read -r не ест \ как escape-символ.
Обработка текста в bash довольно медленная. Отчасти это неизбежно: read должно идти по одному байту за раз (один системный вызов read(2) на байт), чтобы избежать превышения конца строки. Было бы лучше использовать правильный инструмент для работы:
awk -vOFS=';' '{ print $1, $2, $4, $5, $3 }' -- otherfile >file
-- означает, что ваш скрипт не ломается, если otherfile назван как-то глупо, как --version .
Установка разделителя поля вывода на ; означает, что вы можете просто передать несколько полей в качестве аргументов для печати. Оболочка read назначает всю оставшуюся часть строки с пробелами последней переменной, но нет способа сказать, что awk будет разделен только на 5. Если это важно, возможно, просто продолжайте использовать цикл bash, потому что это неудобно в awk. Perl делает это легко, поскольку его split может принимать аргумент max-fields, но запуск намного медленнее, чем awk.
На самом деле, оказалось, что это не так сложно, просто уродливое выражение для написания. Чтобы получить остальную часть строки вместо $5 в awk, цикл по полям все еще теряет свой первоначальный пробел. Моя первая жизнеспособная идея - использовать gensub на $0 (целую строку), чтобы удалить первые 4 поля (то есть не пробел, а затем пробел), оставляя все остальное:
awk -vOFS=';' '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1); print $1, $2, $4, tail, $3 }' -- otherfile >file
Я понял это правильно с первой попытки, но тот факт, что я был впечатлен этим, говорит о читабельности этого awk-кода. >. <
Обратите внимание, что это тот же print что и раньше, но с tail вместо $5 .
echo 'A B c DD e f g f' |
awk -vOFS=\; '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1);
print $1, $2, $4, tail, $3 }'
A;B;DD;e f g f;c
Это было бы более впечатляюще, если бы я мог скопировать / вставить литерал и показать, что он прошел через вывод. Введите один в bash с помощью ^ Q. ctrl-Q означает заключить в кавычки следующее нажатие клавиши как буквальный символ, так как редактирование строки в стиле bash в emacs такое же, как и в действительности emacs.
http://mywiki.wooledge.org/BashFAQ содержит некоторые полезные сведения о сценариях, которые не сломаются, независимо от того, какие данные или имена файлов вы добавляете в сценарий.