Предотвращение файла подстановки
Следующий пример не должен стать сюрпризом. echo *вернет * когда команда была дана в пустой папке. И она вернет имена всех файлов в папке, если папка не была пустой.
paul@ubu1010:~$ mkdir test42
paul@ubu1010:~$ cd test42
paul@ubu1010:~/test42$ echo *
*
paul@ubu1010:~/test42$ touch file42 file33
paul@ubu1010:~/test42$ echo *
file33 file42
Подстановка может быть предотвращена использованием кавычек или обратного слеша, как показано на примере.
paul@ubu1010:~/test42$ echo *
file33 file42
paul@ubu1010:~/test42$ echo \*
*
paul@ubu1010:~/test42$ echo '*'
*
paul@ubu1010:~/test42$ echo "*"
*
IV. pipes and commands
Одним из полномочий командной строки Unix является использование перенаправлений и пайпов (pipes, конвейеров/труб/потоков). Эта глава сначала объяснит перенаправление входящих и исходящих потоков, а так же потоков ошибок. И затем представит пайпы, которые состоят из нескольких команд.
1. stdin, stdout and stderr.Shell (как и почти любая другая команда Linux) забирает входящие данные из stdin (поток 0) направляет исходящие данные в stdout (поток 1) и сообщения об ошибках в stderr(поток 2).
Часто клавиатура служит стандартным вводом для stdin, а стандартным выводом для stdout и stderrслужит монитор. Shell позволяет вам перенаправлять эти потоки.
2. Перенаправление исходящего потока. Stdoutможет быть перенаправлен с помощью знака больше. Когда происходит сканирование строки, shall увидит знак > и очистит файл.
[paul@RHELv4u3 ~]$ echo It is cold today!
It is cold today!
[paul@RHELv4u3 ~]$ echo It is cold today! > winter.txt
[paul@RHELv4u3 ~]$ cat winter.txt
|
|
It is cold today!
[paul@RHELv4u3 ~]$
Обратите внимание, что знак > на самом деле является аббревиатурой от 1>(stdout именуется потоком 1).
Повторим: Когда происходит сканирование строки, shall увидит знак > и очистит файл.Это значит, что даже если команда не будет выполнена, файл будет очищен!
[paul@RHELv4u3 ~]$ cat winter.txt
It is cold today!
[paul@RHELv4u3 ~]$ zcho It is cold today! > winter.txt
-bash: zcho: command not found
[paul@RHELv4u3 ~]$ cat winter.txt
[paul@RHELv4u3 ~]$
Очистка файла использованием > может быть предотвращена установкой опции noclobber.
[paul@RHELv4u3 ~]$ cat winter.txt
It is cold today!
[paul@RHELv4u3 ~]$ set -o noclobber
[paul@RHELv4u3 ~]$ echo It is cold today! > winter.txt
-bash: winter.txt: cannot overwrite existing file
[paul@RHELv4u3 ~]$ set +o noclobber
[paul@RHELv4u3 ~]$
Noclobber может быть отменен с помощью >|.
[paul@RHELv4u3 ~]$ set -o noclobber
[paul@RHELv4u3 ~]$ echo It is cold today! > winter.txt
-bash: winter.txt: cannot overwrite existing file
[paul@RHELv4u3 ~]$ echo It is very cold today! >| winter.txt
[paul@RHELv4u3 ~]$ cat winter.txt
It is very cold today!
[paul@RHELv4u3 ~]$
Используйте >> чтобы добавить вывод в файл. (Записать в конец).
[paul@RHELv4u3 ~]$ echo It is cold today! > winter.txt
[paul@RHELv4u3 ~]$ cat winter.txt
It is cold today!
[paul@RHELv4u3 ~]$ echo Where is the summer ? >> winter.txt
[paul@RHELv4u3 ~]$ cat winter.txt
It is cold today!
Where is the summer ?
[paul@RHELv4u3 ~]$
Перенаправление ошибок
2> stderr.
Перенаправление stderr происходит с помощью 2>. Это может быть очень полезным, чтобы избежать того, что сообщения об ошибке загромоздили весь экран. Пример внизу показывает перенаправление stdout в файл и stderr в /dev/null. Написание 1> имеет тот же смысл что и >.
|
|
[paul@RHELv4u3 ~]$ find / > allfiles.txt 2> /dev/null
[paul@RHELv4u3 ~]$
2>&1
Чтобы перенаправить оба потока сразу в 1 файл используйте 2>&1.
[paul@RHELv4u3 ~]$ find / > allfiles_and_errors.txt 2>&1
[paul@RHELv4u3 ~]$
Обратите внимание, что порядок в данном случае имеет значение. Например, команда
ls > dirlist 2>&1
направляет оба вывода (и стандартный вывод, и стандартные ошибки) в файл dirlist, в то время как команда
ls 2>&1 > dirlist
перенаправляет только стандартный вывод в файл dirlist, потому что стандартный вывод ошибок сделал копию адреса стандартного вывода до того, как стандартный вывод был перенаправлен в dirlist.
Перенаправление ввода.
Перенаправление ввода делается с помощью < (сокращение от 0<).
[paul@RHEL4b ~]$ cat < text.txt
one
two
[paul@RHEL4b ~]$ tr 'onetw' 'ONEZZ' < text.txt
ONE
ZZO
[paul@RHEL4b ~]$
«Здесь» документ (<<here document) это способ задания ввода до того как определенная последовательность (обычно EOF) не встретится. Маркер EOF может быть введен буквально или может быть вызван сочетанием клавишь Ctrl-D.
|
|
[paul@RHEL4b ~]$ cat <<EOF > text.txt
> one
> two
> EOF
[paul@RHEL4b ~]$ cat text.txt
one
two
[paul@RHEL4b ~]$ cat <<brol > text.txt
> brel
> brol
[paul@RHEL4b ~]$ cat text.txt
brel
[paul@RHEL4b ~]$
«Здесь» строка (<<<here string), может быть использована, чтобы напрямую передавать строки команде. Результат такой же, как при использовании echo string | command(но так будет на один меньше запущенный процесс).
paul@ubu1110~$ base64 <<< linux-training.be
bGludXgtdHJhaW5pbmcuYmUK
paul@ubu1110~$ base64 -d <<< bGludXgtdHJhaW5pbmcuYmUK
linux-training.be
Просмотрите rfc 3548 для большей информации о base64.
5.Смешанное перенаправление (confusing redirection).
Shell будет сканировать всю строку до тех пор, пока не будет принято перенаправление. Следующая команда вполне читаема и правильна.
cat winter.txt > snow.txt 2> errors.txt
Однако эта команда тоже правильна, хотя и хуже читается.
2> errors.txt cat winter.txt > snow.txt
Даже эту запись shell прекрасно поймет
< winter.txt > snow.txt 2> errors.txt cat
Быстрая очистка файла
Итак, какой самый быстрый способ очистить файл?
>foo
И какой же самый быстрый способ очистить файл, когда nocobbler активирован?
>|bar
Перемена stdout и stderr
При фильтрации выходного потока, например через обычный канал (|) вы можете только фильтровать стандартный вывод stdout. Скажем, вам надо отфильтровать некоторые незначительные ошибки из потока stderr. Это не может быть сделано напрямую и вам нужно поменять местами (swap) stdout и stderr. Это может быть сделано непосредственно с помощью четвертого потока с номером 3:
|
|
3>&1 1>&2 2>&3 # в 3 копируется 1, в 1 копируется 2, в 2 копируется 3
Эта подобная Башне Ханоя (перемещение возможно только через третий, временный пункт) инструкция использует временный поток 3, чтобы иметь возможность обменять stdout (1) и stderr(2). Ниже приведен пример того, как отфильтровать все записи в потоке stderr, содержащие $error.
$command 3>&1 1>&2 2>&3 | grep -v $error 3>&1 1>&2 2>&3
Но в этом примере это может быть сделано куда боле коротким путем, используя пайп на STDERR:
/usr/bin/$somecommand |& grep -v $error
15.8 Pipes (англ. – трубы/конвейеры)
Один из самых больших преимуществ Linux является использование пайпов.
Пайп занимает стандартный вывод предыдущей команды и посылает его в качестве стандартного ввода для следующей команды. Все команды в пайпах выполняются одновременно.
| Вертикальная черта
Рассмотрим следующий пример.
paul@debian5:~/test$ ls /etc > etcfiles.txt
paul@debian5:~/test$ tail -4 etcfiles.txt
X11
xdg
xml
xpdf
paul@debian5:~/test$
Это можно записать в одной командной строке с помощью пайпа:
paul@debian5:~/test$ ls /etc | tail -4
X11
xdg
xml
xpdf
paul@debian5:~/test$
Пайп представлен вертикальной чертой | между двумя командами.
Несколько пайпов.
В одной командной строке можно использовать несколько пайпов. Все команды в пайпе могут работать одновременно.
paul@deb503:~/test$ ls /etc | tail -4 | tac
xpdf
xml
xdg
X11
Глава 16. Фильтры.
Команды, которые созданы для использования с пайпами, часто называют фильтрами. Фильтры - это небольшие программы, которые делают одну конкретную вещь достаточно эффективно. Они могут быть использованы в качестве строительных блоков. Эта глава познакомит вас с наиболее распространенными фильтрами. Сочетание простых команд и фильтров в длинном пайпе позволяет получить лучшее решение.
Cat
Когда команда cat находится между двумя пайпами, она не делает ничего, кроме передачи потока стандартного ввода на стандартный вывод).
[paul@RHEL4b pipes]$ tac count.txt | cat | cat | cat | cat | cat
five
four
three
two
one
[paul@RHEL4b pipes]$
Tee
Написания длинных пайпов в Unix это забавно, но иногда возникает необходимость в промежуточных результатов. Для этого нам пригодится фильтр tee. Фильтр tee ставит поток стандартного ввода на стандартный вывод, а также в файл. Таким образом, команда tee почти такая же, как и cat, за исключением того, что она имеет два одинаковых выхода.
[paul@RHEL4b pipes]$ tac count.txt | tee temp.txt | tac
one
two
three
four
five
[paul@RHEL4b pipes]$ cat temp.txt
five
four
three
two
one
[paul@RHEL4b pipes]$
Grep
Фильтр grep является довольно известным среди пользователей Unix. Наиболее распространенное использование фильтра grep, является фильтрация строк текста, содержащего (или не содержащего) определенную строку.
[paul@RHEL4b pipes]$ cat tennis.txt
Amelie Mauresmo, Fra
Kim Clijsters, BEL
Justine Henin, Bel
Serena Williams, usa
Venus Williams, USA
[paul@RHEL4b pipes]$ cat tennis.txt | grep Williams
Serena Williams, usa
Venus Williams, USA
Вы можете написать этот фильтр без фильтра cat.
[paul@RHEL4b pipes]$ grep Williams tennis.txt
Serena Williams, usa
Venus Williams, USA
Одним из самых полезных вариантов фильтра является grep -i, который фильтрует, несмотря на регистр.
[paul@RHEL4b pipes]$ grep Bel tennis.txt
Justine Henin, Bel
[paul@RHEL4b pipes]$ grep -i Bel tennis.txt
Kim Clijsters, BEL
Justine Henin, Bel
[paul@RHEL4b pipes]$
Другая очень полезная опция grep -v, которая выводит строки, не удовлетворяющие введенной строке.
[paul@RHEL4b pipes]$ grep -v Fra tennis.txt
Kim Clijsters, BEL
Justine Henin, Bel
Serena Williams, usa
Venus Williams, USA
[paul@RHEL4b pipes]$
И, конечно, оба варианта могут быть объединены, чтобы отфильтровать все строки, не содержащие введенные строки и без учета регистра.
[paul@RHEL4b pipes]$ grep -vi usa tennis.txt
Amelie Mauresmo, Fra
Kim Clijsters, BEL
Justine Henin, Bel
[paul@RHEL4b pipes]$
С grep –A1 на экран также выводится одна строка, которая идет после строки, в которой содержится исходный запрос.
paul@debian5:~/pipes$ grep -A1 Henin tennis.txt
Justine Henin, Bel
Serena Williams, usa
С grep –B1 на экран выводится одна строка, которая идет до строки, в которой содержится исходный запрос.
paul@debian5:~/pipes$ grep -B1 Henin tennis.txt
Kim Clijsters, BEL
Justine Henin, Bel
С grep –C1 на экран выводится одна строка, которая идет до и после строки, в которой содержится исходный запрос. Все эти три опции (A,B и C) могут показывать любое количество строк (например, A2, B4 или C20)
paul@debian5:~/pipes$ grep -C1 Henin tennis.txt
Kim Clijsters, BEL
Justine Henin, Bel
Serena Williams, usa
Cut
Фильтр cutможет выбирать столбцы из файлов, в зависимости от разделителя (т.е. например, если в файле слова написаны через :, и задать в качестве разделителя пробел, то «столбец» в каждой строке будет только один) или количества байт. На примере ниже, фильтр cut используют, чтобы разделить имя пользователя и id пользователя в файле /etc/passwd. Используется двоеточие в качестве разделителя, и выбираются поля 1 и 3.
[[paul@RHEL4b pipes]$ cut -d: -f1,3 /etc/passwd | tail -4
Figo:510
Pfaff:511
Harry:516
Hermione:517
[paul@RHEL4b pipes]$
При использовании пробела в качестве разделителя для cut, вы должны взять его в “ “ кавычки.
[paul@RHEL4b pipes]$ cut -d" " -f1 tennis.txt
Amelie
Kim
Justine
Serena
Venus
[paul@RHEL4b pipes]$
В этом примере cut используется для отображения со второго по седьмой символ /etc/passwd.
[paul@RHEL4b pipes]$ cut -c2-7 /etc/passwd | tail -4
igo:x:
faff:x
arry:x
ermion
[paul@RHEL4b pipes]$
Tr
Вы можете заменять символы с помощью фильтра tr. На скриншоте видно замену всех “е” на “E”.
[paul@RHEL4b pipes]$ cat tennis.txt | tr 'e' 'E'
AmEliE MaurEsmo, Fra
Kim ClijstErs, BEL
JustinE HEnin, BEl
SErEna Williams, usa
VEnus Williams, USA
Здесь мы заменяем все строчные буквы на заглавные с помощью определения двух диапазонов.
[paul@RHEL4b pipes]$ cat tennis.txt | tr 'a-z' 'A-Z'
AMELIE MAURESMO, FRA
KIM CLIJSTERS, BEL
JUSTINE HENIN, BEL
SERENA WILLIAMS, USA
VENUS WILLIAMS, USA
[paul@RHEL4b pipes]$
Здесь мы заменяем все символы новой строки пробелами.
[paul@RHEL4b pipes]$ cat count.txt
one
two
three
four
five
[paul@RHEL4b pipes]$ cat count.txt | tr '\n' ' '
one two three four five [paul@RHEL4b pipes]$
Фильтр tr -s можно использовать, чтобы заменить несколько одинаковых символов на один.
[paul@RHEL4b pipes]$ cat spaces.txt
one two three
four five six
[paul@RHEL4b pipes]$ cat spaces.txt | tr -s ' '
one two three
four five six
[paul@RHEL4b pipes]$
Вы также можете использовать tr, чтобы "шифровать" тексты с помощью rot13.
[paul@RHEL4b pipes]$ cat count.txt | tr 'a-z' 'nopqrstuvwxyzabcdefghijklm'
bar
gjb
guerr
sbhe
svir
[paul@RHEL4b pipes]$ cat count.txt | tr 'a-z' 'n-za-m'
bar
gjb
guerr
sbhe
svir
[paul@RHEL4b pipes]$
В этом последнем примере мы используем tr -d для удаления символов.
paul@debian5:~/pipes$ cat tennis.txt | tr -d e
Amli Maursmo, Fra
Kim Clijstrs, BEL
Justin Hnin, Bl
Srna Williams, usa
Vnus Williams, USA
Wc
Посчитать количество слов, строк и символов довольно легко с фильтром wc.
[paul@RHEL4b pipes]$ wc tennis.txt
5 15 100 tennis.txt
[paul@RHEL4b pipes]$ wc -l tennis.txt
5 tennis.txt
[paul@RHEL4b pipes]$ wc -w tennis.txt
15 tennis.txt
[paul@RHEL4b pipes]$ wc -c tennis.txt
100 tennis.txt
[paul@RHEL4b pipes]$
Sort
Фильтр sort по умолчанию сортирует слова в алфавитном порядке.
paul@debian5:~/pipes$ cat music.txt
Queen
Brel
Led Zeppelin
Abba
paul@debian5:~/pipes$ sort music.txt
Abba
Brel
Led Zeppelin
Queen
Фильтр sort имеет много опций для настройки его использования. Этот пример показывает, сортировку различных столбцов (колонка 1 или столбец 2).
[paul@RHEL4b pipes]$ sort -k1 country.txt
Belgium, Brussels, 10
France, Paris, 60
Germany, Berlin, 100
Iran, Teheran, 70
Italy, Rome, 50
[paul@RHEL4b pipes]$ sort -k2 country.txt
Germany, Berlin, 100
Belgium, Brussels, 10
France, Paris, 60
Italy, Rome, 50
Iran, Teheran, 70
На следующем примере показана разница между алфавитной и числовой сортировкой (второго столбца на третий).
[paul@RHEL4b pipes]$ sort -k3 country.txt
Belgium, Brussels, 10
Germany, Berlin, 100
Italy, Rome, 50
France, Paris, 60
Iran, Teheran, 70
[paul@RHEL4b pipes]$ sort -n -k3 country.txt
Belgium, Brussels, 10
Italy, Rome, 50
France, Paris, 60
Iran, Teheran, 70
Germany, Berlin, 100
Uniq
С фильтром uniq вы можете удалять дубликаты записей из отсортированного списка.
paul@debian5:~/pipes$ cat music.txt
Queen
Brel
Queen
Abba
paul@debian5:~/pipes$ sort music.txt
Abba
Brel
Queen
Queen
paul@debian5:~/pipes$ sort music.txt |uniq
Abba
Brel
Queen
Фильтром uniq можно так же найти количество повторений с помощью опции –c.
paul@debian5:~/pipes$ sort music.txt |uniq -c
1 Abba
1 Brel
2 Queen
Comm
Сравнение потоков (или файлов) можно сделать с помощью фильтра comm. По умолчанию comm выводит три столбца. В этом примере, Abba, Cure и Queen в обоих списках, Bowie и Sweet только в первом файле, Turner только во втором.
paul@debian5:~/pipes$ cat > list1.txt
Abba
Bowie
Cure
Queen
Sweet
paul@debian5:~/pipes$ cat > list2.txt
Abba
Cure
Queen
Turner
paul@debian5:~/pipes$ comm list1.txt list2.txt
Abba
Bowie
Cure
Queen
Sweet
Turner
Результат сортировки фильтром comm иногда легче читать, если выводить только один столбец. Цифрами указывается, какие столбцы не должно отображаться.
paul@debian5:~/pipes$ comm -12 list1.txt list2.txt
Abba
Cure
Queen
paul@debian5:~/pipes$ comm -13 list1.txt list2.txt
Turner
paul@debian5:~/pipes$ comm -23 list1.txt list2.txt
Bowie
Sweet
Od
Людям в Европе нравится работать с кодировкой ASCII, но компьютер хранит файлы в байтах. В приведенном ниже примере создается простой файл, а затем используется фильтр od, чтобы показать содержимое файла в шестнадцатеричном виде.
paul@laika:~/test$ cat > text.txt
abcdefg
1234567
paul@laika:~/test$ od -t x1 text.txt
0000000 61 62 63 64 65 66 67 0a 31 32 33 34 35 36 37 0a
0000020
Этот файл можно также открыть в восьмеричном.
paul@laika:~/test$ od -b text.txt
0000000 141 142 143 144 145 146 147 012 061 062 063 064 065 066 067 012
0000020
А вот файл в ASCII (или обратным слешем)
paul@laika:~/test$ od -c text.txt
0000000 a b c d e f g \n 1 2 3 4 5 6 7 \n
0000020.
Sed
Фильтр sed -это потоковый редактор, который может выполнять функции редактирования в потоке, с использованием регулярных выражений.
paul@debian5:~/pipes$ echo level5 | sed 's/5/42/'
level42
paul@debian5:~/pipes$ echo level5 | sed 's/level/jump/'
jump5
Добавив g,вы произведете глобальную замену (всех встречающихся искомых элементов в строке).
paul@debian5:~/pipes$ echo level5 level7 | sed 's/level/jump/'
jump5 level7
paul@debian5:~/pipes$ echo level5 level7 | sed 's/level/jump/g'
jump5 jump7
С опцией d вы можете удалять строки из потока, содержащие символ.
paul@debian5:~/test42$ cat tennis.txt
Venus Williams, USA
Martina Hingis, SUI
Justine Henin, BE
Serena williams, USA
Kim Clijsters, BE
Yanina Wickmayer, BE
paul@debian5:~/test42$ cat tennis.txt | sed '/BE/d'
Venus Williams, USA
Martina Hingis, SUI
Serena williams, USA
Примеры пайпов
who | wc
Как много пользователей находится в системе ?
[paul@RHEL4b pipes]$ who
root tty1 Jul 25 10:50
paul pts/0 Jul 25 09:29 (laika)
Harry pts/1 Jul 25 12:26 (barry)
paul pts/2 Jul 25 12:26 (pasha)
[paul@RHEL4b pipes]$ who | wc -l
4
who | cut | sort
Показать отсортированный список зарегистрированных пользователей.
[paul@RHEL4b pipes]$ who | cut -d' ' -f1 | sort
Harry
paul
paul
root
Показать отсортированный список зарегистрированных пользователей, но каждого пользователя показать только один раз.
[paul@RHEL4b pipes]$ who | cut -d' ' -f1 | sort | uniq
Harry
paul
root
grep | cut
Показать список всех учетных записей пользователей Bash на этом компьютере. Учетные записи пользователей будут подробно описаны позже.
paul@debian5:~$ grep bash /etc/passwd
root:x:0:0:root:/root:/bin/bash
paul:x:1000:1000:paul,,,:/home/paul:/bin/bash
serena:x:1001:1001::/home/serena:/bin/bash
paul@debian5:~$ grep bash /etc/passwd | cut -d: -f1
root
paul
serena
Дата добавления: 2018-04-05; просмотров: 328; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!