Главное, :>не один оператор. Это может быть легче понять, если вы прочитаете это как : > fileвместо этого.
jpfx1342
Это означает , что человек , пишущий сценарий должен был перенаправлен вывод петли в файл: while read A B C D E; do echo "$A;$B;$D;$E;$C"; done < otherfile > file. Или, еще лучше, они должны были использовать правильный инструмент для работы, awk, как предложил Питер . Кроме того, вы почти всегда хотите использовать -rпереключатель сread .
Том Фенек
Вне башни это был бы смайлик для вороны.
SMCI
Ответы:
46
Там было:> в строке bash-скрипта. Что это значит?
:> file
Это краткий способ сказать:
Если fileне существует, то создайте его, иначе обрежьте его до 0байтов.
Это означает, что вы можете быть уверены, что оно fileсуществует и оно пустое.
Вы также можете использовать, > fileно :> fileявляется более портативным.
Я не понимаю вторую строку. Я думал, что читаю читаю переменные. Командное эхо тоже странно. Могли бы вы объяснить?
diego9403
Я не эксперт по Unix, но я думаю, что вторая строка читает otherfileи echoвыводит их file. Он также делает переменные из того, что читает ... Если вы хотите получить определенный ответ, пожалуйста, задайте свой вопрос.
Дэвид Постилл
2
@ diego9403: readполучает информацию от стандартного ввода. Само по себе, он будет читать то, что вы печатаете. Поскольку stdin был перенаправлен <otherfileна, содержимое otherfile"вводится" в stdin. Таким образом, readзначения получаются построчно в переменные $ A, $ B, $ C, $ D и $ E.
Slebetman
Так что это просто более неясная альтернатива truncateиз coreutils?
Федерико Полони
1
@PeterCordes Я не имел в виду «неясный», как в «это необычно», но как «это менее понятно для читателя».
Федерико Полони
29
Это похоже на причудливый способ создания нового файла. In bash:является пустой командой:
$ type :: is a shell builtin
$ help ::::Null command.No effect; the command does nothing.ExitStatus:Always succeeds.
:это сокращение для true. Возможно в некоторых оболочках, trueразве не встроенный? Оба встроены в Bash.
Питер Кордес
12
:это другое имя для true. Оба встроены в bash, но нет /bin/:, только a /bin/true. Перенаправление вывода вызывает оболочку open(2)в файл с помощью O_CREAT|O_TRUNC. Если ничего не написано, оно остается на нулевой длине.
Соединение этих двух частей :> file- довольно распространенная идиома для усечения файлов. : >fileТем не менее, большинство людей пытались бы сделать это менее странным, когда писали .
Поскольку вы спросили в комментарии о 2-й строке, я превращу свои комментарии в ответ. (даже если вы не задавали это в своем вопросе.)
2-я строка - это цикл, который читает строки otherfileв некоторые именованные переменные. Тело цикла использует echoдля печати их с ;разделителями вместо того, что было раньше. fileзакрывается и повторно открывается (для добавления) каждую итерацию, потому что перенаправление находится внутри цикла. Использование while ...;do read -r ...;done <otherfile >fileбудет меньше отстой, и избежать необходимости сначала обрезать файл. read -rне ест \как побег
Обработка текста в bash довольно медленная. Частично это неизбежно: readприходится идти по одному байту за раз (один read(2)системный вызов на байт), чтобы избежать превышения конца строки. Было бы лучше использовать правильный инструмент для работы:
--означает, что ваш скрипт не ломается, если otherfileназван как-то глупо, как --version.
Установка разделителя поля вывода на ;означает, что вы можете просто передать несколько полей в качестве аргументов для печати. Оболочка readприсваивает последнюю переменную всей оставшейся части строки с пробелами, но нет способа сказать, чтобы awk делился только на 5. Если это важно, возможно, просто продолжайте использовать цикл bash, потому что это неудобно в awk. Perl делает это легко, поскольку он splitможет принимать аргументы max-fields, но запускать его намного медленнее, чем awk.
На самом деле, оказалось, что это не так сложно, просто уродливое выражение для написания. Для того, чтобы получить «остальную часть строки» вместо $5awk, цикл по полям все еще теряет свой первоначальный пробел. Моя первая жизнеспособная идея заключается в том, чтобы использовать gensubна $0(всю линии) , чтобы удалить первое 4 поля (т.е. не пространство с последующим пробелом), оставляя все остальное:
Я понял это правильно с первой попытки, но тот факт, что я был впечатлен этим, говорит о читабельности этого 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 содержит некоторые полезные сведения о сценариях, которые не сломаются, независимо от того, какие данные или имена файлов вы добавляете в сценарий.
:>
не один оператор. Это может быть легче понять, если вы прочитаете это как: > file
вместо этого.while read A B C D E; do echo "$A;$B;$D;$E;$C"; done < otherfile > file
. Или, еще лучше, они должны были использовать правильный инструмент для работы, awk, как предложил Питер . Кроме того, вы почти всегда хотите использовать-r
переключатель сread
.Ответы:
Там было:> в строке bash-скрипта. Что это значит?
Это краткий способ сказать:
file
не существует, то создайте его, иначе обрежьте его до0
байтов.Это означает, что вы можете быть уверены, что оно
file
существует и оно пустое.Вы также можете использовать,
> file
но:> file
является более портативным.См. Вопрос переполнения стека. Какова цель GNU Bash Builtin? для дополнительной информации.
источник
otherfile
иecho
выводит ихfile
. Он также делает переменные из того, что читает ... Если вы хотите получить определенный ответ, пожалуйста, задайте свой вопрос.read
получает информацию от стандартного ввода. Само по себе, он будет читать то, что вы печатаете. Поскольку stdin был перенаправлен<otherfile
на, содержимоеotherfile
"вводится" в stdin. Таким образом,read
значения получаются построчно в переменные $ A, $ B, $ C, $ D и $ E.truncate
из coreutils?Это похоже на причудливый способ создания нового файла. In
bash
:
является пустой командой:>
перенаправляет вывод:
в файл.источник
>
делает:
это сокращение дляtrue
. Возможно в некоторых оболочках,true
разве не встроенный? Оба встроены в Bash.:
это другое имя дляtrue
. Оба встроены в bash, но нет/bin/:
, только a/bin/true
. Перенаправление вывода вызывает оболочкуopen(2)
в файл с помощьюO_CREAT|O_TRUNC
. Если ничего не написано, оно остается на нулевой длине.Соединение этих двух частей
:> file
- довольно распространенная идиома для усечения файлов.: >file
Тем не менее, большинство людей пытались бы сделать это менее странным, когда писали .Поскольку вы спросили в комментарии о 2-й строке, я превращу свои комментарии в ответ. (даже если вы не задавали это в своем вопросе.)
2-я строка - это цикл, который читает строки
otherfile
в некоторые именованные переменные. Тело цикла используетecho
для печати их с;
разделителями вместо того, что было раньше.file
закрывается и повторно открывается (для добавления) каждую итерацию, потому что перенаправление находится внутри цикла. Использованиеwhile ...;do read -r ...;done <otherfile >file
будет меньше отстой, и избежать необходимости сначала обрезать файл.read -r
не ест\
как побегОбработка текста в bash довольно медленная. Частично это неизбежно:
read
приходится идти по одному байту за раз (одинread(2)
системный вызов на байт), чтобы избежать превышения конца строки. Было бы лучше использовать правильный инструмент для работы:--
означает, что ваш скрипт не ломается, еслиotherfile
назван как-то глупо, как--version
.Установка разделителя поля вывода на
;
означает, что вы можете просто передать несколько полей в качестве аргументов для печати. Оболочкаread
присваивает последнюю переменную всей оставшейся части строки с пробелами, но нет способа сказать, чтобы awk делился только на 5. Если это важно, возможно, просто продолжайте использовать цикл bash, потому что это неудобно в awk. Perl делает это легко, поскольку онsplit
может принимать аргументы max-fields, но запускать его намного медленнее, чем awk.На самом деле, оказалось, что это не так сложно, просто уродливое выражение для написания. Для того, чтобы получить «остальную часть строки» вместо
$5
awk, цикл по полям все еще теряет свой первоначальный пробел. Моя первая жизнеспособная идея заключается в том, чтобы использоватьgensub
на$0
(всю линии) , чтобы удалить первое 4 поля (т.е. не пространство с последующим пробелом), оставляя все остальное:Я понял это правильно с первой попытки, но тот факт, что я был впечатлен этим, говорит о читабельности этого awk-кода. >. <
Обратите внимание, что это так же,
print
как и раньше, но сtail
вместо$5
.Это было бы более впечатляюще, если бы я мог скопировать / вставить литерал и показать, что он прошел через вывод. Введите один в bash с помощью ^ Q. ctrl-Q означает заключить в кавычки следующее нажатие клавиши как буквальный символ, так как редактирование строки в стиле bash в emacs такое же, как и в действительности emacs.
http://mywiki.wooledge.org/BashFAQ содержит некоторые полезные сведения о сценариях, которые не сломаются, независимо от того, какие данные или имена файлов вы добавляете в сценарий.
источник