Professional Documents
Culture Documents
Linux - Shell.programming - pocket.primer.B0C7RNYF9Z 133 325
Linux - Shell.programming - pocket.primer.B0C7RNYF9Z 133 325
Примерно извикване на листинг 4.18 е тук, което вече е добавило трима потребители:
Списък на потребителите
==============
абВГДЕ
123 456 888
777
----------------------------
МАСИВИ В BASH
Списък 4.19 дефинира масива с имена , който се инициализира с пет низа, започвайки
от индекс 0 до индекс 4. Двата оператора за ехо показват първия и втория елемент в
масива с имена , които са съответно с индекс 0 и 1. Резултатът от листинг 4.19 е тук:
${array_name[*]} $
{array_name[@]}
#!/bin/bash
numbers="1 2 3 4 5 6 7 8 9 10" array1=( 'echo "$numbers" ')
total1=0
общо 2=0
Общо1: 012345678910
Общо 2: 55
аз
РАБОТА С МАСИВИ
#!/bin/bash
# метод №1:
плодове[0]="ябълка"
плодове[1]="банан"
плодове[2]="череша"
плодове[3]="портокал"
плодове[4]="круша" ехо
"първи плод: ${fruits[0]}"
# метод #2:
декларирайте -a fruits2=(ябълка банан череша портокал круша) echo "първи плод: $
{fruits2[0]}"
Джейн Смит
Джон Джоунс
Дейв Едуардс
#!/bin/bash
IFS=""
names="names.txt" contents1=( `cat
"$names"` )
Първи цикъл:
Machine Translated by Google
Джейн
Смит
Джон
Джоунс
Дейв
Едуардс
Втори цикъл:
Джейн Смит
Джон Джоунс
Дейв Едуардс
#!/bin/bash
# компактна версия на кода по-късно в този скрипт: #items() { за ред в "${@}" ; do printf "%s\n" "$
{line}" ; Свършен ; } #aa=( 7 -4 -e ); елементи „${aa[@]}“
done
Листинг 4.25 съдържа функцията items() , която показва съдържанието на масива arr ,
който е инициализиран преди извикването на тази функция. Резултатът е показан тук:
123
-abc
моите данни
#!/bin/bash
плодове[0]="ябълка"
плодове[1]="банан"
плодове[2]="череша"
плодове[3]="портокал"
плодове[4]="круша"
# дължина на масива:
arrlength=${#fruits[@]} echo
"дължина: ${#fruits[@]}"
" ${плодове[$i-1]}
дължина: 5
елемент 1 от 5: елемент ябълка 2 от 5:
елемент банан 3 от 5: елемент череша 4 от
РЕЗЮМЕ
ГЛАВА 5
T
неговата глава ви въвежда в многостранния grep команда, чиято цел
е да вземете поток от текстови данни и да го намалите само до частите, които ви интересуват
относно. Командата
grep е полезна не само сама по себе си, но и в
връзка с други команди, особено командата find . Това
глава съдържа много примери за кратки кодове, които илюстрират различни опции на
командата.
grep Някои примерни кодове илюстрират как да комбинирате командата grep
с команди от предишни глави.
Първата част на тази глава представя командата, използвана в
grep
изолация, комбинирана с метасимволите на регулярния израз (от
Глава 1), а също и с кодови фрагменти, които илюстрират как да използвате някои от
опции на командата.
grepСлед това ще научите как да съпоставяте диапазони от
редове и как да използвате обратните препратки и метасимволите „escape“ в
grep.
Втората част на тази глава ви показва как да използвате grep за команда
намиране на празни редове и общи редове в набори от данни, както и използването на ключове
•
grep abc *sh показва всички редове на abc във файлове със суфикс sh.
•
grep -i abc *sh е същата като предходната заявка, но регистър
нечувствителен.
•
grep -l abc *sh показва всички имена на файлове със суфикс sh , които съдържат
абв.
•
grep -n abc *sh показва всички номера на редове на срещанията на
низ abc във файлове със суфикс sh.
•
grep abc *sh | grep def съвпада с редове, съдържащи abc И def.
•
grep "abc\|def" *sh съвпада с редове, съдържащи abc ИЛИ def.
Празният регулярен израз съответства на празния низ (т.е. ред във входния поток
без данни). Два регулярни израза могат да бъдат съединени от инфикс оператора „|.“
Когато се използва по този начин, операторът на инфикс се държи точно като
логически израз „ИЛИ“, който насочва командата да върне всеки ред,
grepкойто съответства
abcd
аб
абв
cd
defg .*.
..
Следващата команда изброява редовете с дължина две в lines.txt , които съдържат две
точки (обратната наклонена черта казва на grep да интерпретира точките като действителни
точки, а не като метазнаци):
аб
cd
..
този раздел съдържа еклектична комбинация от такива команди, които обработват общи
сценарии.
В следващите примери имаме четири текстови файла (два .sh и два .txt) и два
документа на Word в директория. Низът abc се намира на един ред в abc1.txt и на три
реда в abc3.sh. Низът ABC се намира на два реда в ABC2.txt и на четири реда в ABC4.sh.
Забележете, че abc не се намира в ABC файлове и ABC не се намира в abc файлове.
ls *
Следният кодов фрагмент търси срещания на низа abc във всички файлове в
текущата директория, които имат sh като суфикс:
ABC4.sh:0
abc3.sh:3
Опцията -v "обръща" съвпадащия низ, което означава, че изходът се състои от редовете, които
не съдържат посочения низ (ABC не съвпада, защото -i не се използва и ABC4.sh има изцяло празен
ред):
grep -l abc *
abc1.txt abc3.sh
abc.doc
Използвайте опцията -il , за да покажете имената на файловете, които съдържат определен низ, като използвате
завършва с -abc
abc е в средата
Machine Translated by Google
Предходните команди съответстват на редове, където посоченият низ е подниз на по-дълъг низ във файла. Например,
предходните команди ще съпоставят срещанията на abc , както и abcd, dabc, abcde и т.н.
четири пет
Следващата команда намира всички редове, които съдържат низовете едно и три с
произволен брой междинни знаци, където съвпадението включва сравнение без значение
за главни и малки букви:
grep -iv "едно.*три" колони4.txt 123 ЕДНО ДВЕ 456 три четири
Понякога трябва да търсите във файл за наличието на един от два низа. Например,
следната команда намира файловете, които съдържат
начало или край:
abc3.sh
Този раздел съдържа някои прости команди от един ред, които комбинират
grep командата с класове знаци.
здравей свят1
здравей свят3
здравей свят3 две здравей
свят3 три
здравей2.txt:2
hello3.txt:3 grep -l hello
hello2.txt
hello3.txt grep -c
„2$“ предотвратява прихващането на файлове, които имат 12, 32 или 142 съвпадения
(които завършват на :12, :32 и :142).
Какво ще стане, ако искаме да покажем „две или повече“ (както в „2 или повече грешки в
регистрационния файл“)? Вместо това бихте използвали командата за обръщане (-v) , за да
изключите броя точно 0 или точно 1.
здравей3.txt:3
hello2.txt
hello3.txt
Резултатът е тук:
9 едно или
още 10 думи 11 и ако 12
използвате котката
13 команда на
14 съдържание на файла 15
превъртане
Machine Translated by Google
Резултатът е тук:
7 и всеки ред
11 и ако 13 командвате
Тази команда включва интервал след думата и по този начин изключва реда с
думата команда:
Резултатът е тук:
7 и всеки ред
11 и ако вие
11 и ако 13 командвате
11 и ако вие
етикет като ГРЕШКА или Предупреждение, цифров код или дата). Тази команда показва
редовете, които започват с думата и:
глава -15 дълъг файл.txt |опашка -9 | grep "^and " и всеки ред
и ако ти
Командата head обаче не показва номерата на редовете на текстов файл, така че стилът
„cat first“ (cat -n добавя номера на редове) се използва в по-ранните примери, когато искате да
видите номерата на редовете, въпреки че този стил е по-малко ефективен. По принцип искате
да добавите допълнителна команда към канала само ако добавя стойност, в противен случай е
по-добре да започнете с директно извикване на файловете, които се опитвате да обработите с
първата команда в канала, като приемете синтаксиса на командата може да чете имена на
файлове.
Обратната препратка '\n', където n е една цифра, съвпада с подниза, съпоставен преди
това с n-тия подизраз в скоби на регулярния израз. Например grep '\(a\)\1' съвпада с aa и grep '\
(a\)\2' съвпада с aaa.
Machine Translated by Google
Ако искате да разрешите по-малко от три цифри, можете да използвате израза {1,3},
който съвпада с 1, 2 или 3 цифри в третия блок. В ситуация, в която някой от четирите
блока може да има по-малко от три знака, трябва да използвате следния тип синтаксис
във всичките четири блока:
едно ено
ЕДНО ЕНО
едно ено
ЕДНО ЕНО
ЕДНО ДВЕ OWT ENO
Идеята е следната: първият \(.\) съответства на набор от букви, последван от втори \(.\) , който съответства на набор
от букви, последван от произволен брой междинни знаци. Последователността \2\1 обръща реда на съвпадащите набори
(.\).
3:
едно ено
ЕДНО ЕНО
ЕДНО ДВЕ OWT ENO
четири пет
4520
5530
6550
7200
8000
4520 12
4520 15
5530 5
5530 12
6550 0
6550 8
7200 50
7200 10
7200 30
8000 25
8000 45
8000 90
едно ено
ЕДНО ДВЕ OWT ENO
The xargs командата често се използва заедно с командата find в bash. Например,
можете да търсите файловете в текущата директория (включително поддиректории),
които имат суфикс sh и след това да проверите кой от тези файлове съдържа низа abc,
както е показано тук:
дни и предава този списък към командата xargs , която показва файловете, които
съдържат низа abc (без значение за малки и големи букви).
Ако подадете твърде много имена на файлове към командата xargs , ще видите „също
много файлове“ съобщение за грешка. В тази ситуация опитайте да вмъкнете grep
допълнителни команди преди
xargsкомандата, за да намалите броя на файловете, които са
въведени в командата.
xargs
Ако работите с NodeJS, знаете, че директорията node_modules
съдържа голям брой файлове. В повечето случаи вероятно искате да изключите
файловете в тази директория, когато търсите низ, и -v
опцията е идеална за тази ситуация. Следващата команда изключва файловете
в директорията node_modules , докато търсите имената на HTML
Machine Translated by Google
файлове, които съдържат низа src и пренасочване на списъка с имена на файлове към
файла src_list.txt (и също пренасочване на съобщения за грешка към /dev/null):
намирам . -print |grep -v възел |xargs grep -il src >src_list.txt 2>/dev/null
намирам . -print |grep -v възел |xargs grep -il src |xargs grep -il angular >angular_list.txt 2>/dev/null
Има поне три начина за търсене на низ в един или повече zip файлове. Като пример,
да предположим, че искате да определите кои zip файлове съдържат SVG документи.
Когато има много zip файлове в директория, изходът от предходния цикъл може да
бъде подробен, в който случай трябва да превъртите назад и вероятно да копирате/
поставите имената на файловете, които всъщност съдържат SVG документи, в отделен
файл. По-добро решение е да поставите предходния цикъл в обвивка и да пренасочите
изхода му. Например, създайте файла findsvg.sh , чието съдържание е предходният цикъл,
и след това извикайте тази команда:
Machine Translated by Google
2000
22000
10000
3000
ключ="2000"
foundkey=истина друго
foundkey=false fi
Списък 5.6 съдържа условна логика if/else за определяне дали файлът mykeys.txt
съдържа стойността на $key (която е инициализирана като 2000).
Стартирайте кода в листинг 5.6 и ще видите следния резултат:
grep -w $ ключ
По този начин във файлове, които имат дублирани редове, можете да преброите броя на редовете
които съответстват на ключа чрез предходния кодов фрагмент. Друг начин да го направите
включва използването на wc -l, което показва броя на редовете.
добавяне като „+“ (1 или повече срещания на предишен знак), „?“ (0 или 1
появяване на предишен знак) и „|“ (алтернативно съвпадение). Командата е почти егреп
идентична с grep -E, заедно с някои предупреждения, които са
описан онлайн:
https://www.gnu.org/software/grep/manual/html_node/Basic-vs-Extended.html
следният кодов фрагмент съвпада с редове, които започват с abc или завършват с четири и
празно място:
https://superuser.com/questions/508881/what-is-the-dif erence-between-grep-
pgrep-egrep-fgrep
'
ехо $x |tr -s ' '\н'
Резултатът е тук:
Machine Translated by Google
ghi
абв
Ghi
123
#def5
123z
'
ехо $x |tr -s ' '\n' |egrep "^[a-zA-Z]+$"
Резултатът е тук:
ghi
абв
Ghi
Ако също искате да сортирате изхода и да отпечатате само уникалните думи, използвайте
тази команда:
'
ехо $x |tr -s ' '\n' |egrep "^[a-zA-Z]+$" |sort | уникален
Резултатът е тук:
123
123z
Ghi
абв
ghi
'
ехо $x |tr -s ' '\n' |egrep "^[0-9]+$" |sort | уникален
Резултатът е тук:
123
'
ехо $x |tr -s ' '\n' |egrep "^[a-zA-Z0-9]+$" |sort | уникален
Резултатът е тук:
123
123z
Ghi
абв
ghi
Можете да замените echo $x с набор от данни, за да извлечете само азбучни низове от този
набор от данни.
(„бърза грешка“) е същата като grep -F и въпреки че fgrep е отхвърлена, тя все още се
поддържа, за да позволи на историческите приложения, които разчитат на тях, да работят
немодифицирани. В допълнение, някои по-стари системи може да не поддържат опцията -F за
командата grep , така че те използват командата fgrep . Ако наистина искате да научите повече за
командата fgrep , потърсете уроци в Интернет.
намерите конкретни редове в набор от данни и след това да „слеете“ двойки редове, за да създадете нов набор от данни. Това е
много подобно на това, което прави командата за присъединяване в релационна база данни. Листинг 5.7 показва съдържанието
F1,F2,F3,M0,M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12
1,KLM,,1.4,,0.8,,1.2,,1.1,,,2.2 ,,,1.4
1,KLMAB,,0.05,,0.04,,0.05,,0.04,,,0.07,,,0.05
Machine Translated by Google
1,TP,,7.4,,7.7,,7.6,,7.6,,,8.0,,,7.3
1,XYZ,,4.03,3.96,,3.99,,3.84,4.12,,,,4.04,, 2,KLM, ,0.9,0.7,,0.6,,0.8,0.5,,,,0.5,,
2,KLMAB,,0.04,0.04,,0.03,,0.04,0.03,,,,0.03,,
2,EGFR,,99,99 ,,99,,99,99,,,,99,, 2,TP,,6.6,6.7,,6.9,,6.6,7.1,,,,7.0,,
3,KLM,,0.9,0.1,,0.5, ,0.7,,0.7,,,0.9,,
3,KLMAB,,0.04,0.01,,0.02,,0.03,,0.03,,,0.03,,
3,PLT,,224,248,,228,,251,,273, ,,206,,
3,XYZ,,4.36,4.28,,4.58,,4.39,,4.85,,,4.47,, 3,RDW,,13.6,13.7,,13.8,,14.1,,14.0,,,13.4, ,
3,WBC,,3.9,6.5,,5.0,,4.7,,3.7,,,3.9,, 3,A1C,,5.5,5.6,,5.7,,5.6,,5.5,,,5.3,,
4,KLM ,,1.2,,0.6,,0.8,0.7,,,0.9,,,1.0, 4,TP,,7.6,,7.8,,7.6,7.3,,,7.7,,,7.7,
5,KLM,,0.7, ,0.8,,1.0,0.8,,0.5,,,1.1,, 5,KLM,,0.03,,0.03,,0.04,0.04,,0.02,,,0.04,,
5,TP,,7.0,,7.4,, 7.3,7.6,,7.3,,,7.5,,
5,XYZ,,4.73,,4.48,,4.49,4.40,,,4.59,,,4.63,
inputfile="test1.csv"
outputfile="joinedlines.csv" tmpfile2="tmpfile2"
# шаблони за съвпадение:
klm1="1,KLM,"
klm5="5,KLM,"
xyz1="1,XYZ,"
xyz5="5,XYZ,"
#изход:
#klm1,xyz1
#klm5,xyz5
1,KLM,,1.4,,0.8,,1.2,,1.1,,,2.2,,,1.41,X
YZ,,4.03,3.96,,3.99,,3.84,4.12,,,,4.04,,
5,KLM,,0.7,,0.8,,1.0,0.8,,0.5,,,1.1,,5,KLM
,,0.03,,0.03,,0.04,0.04,,0.02,,,0.04,,5,X
YZ,,4.73,,4.48,,4.49,4.40,,,4.59,,,4.63,
Както можете да видите, задачата в този раздел се решава лесно чрез grep
команда. Обърнете внимание, че е необходимо допълнително почистване на данни, за да се справи с празните
полета в изхода.
РЕЗЮМЕ
ГЛАВА 6
команда (grep, cat, ls, find и т.н.) в начина, по който може да приема данни, изходни данни и
съвпадение на шаблони с регулярни изрази.
Някои от по-честите употреби на sed включват отпечатване на съвпадащи редове, изтриване
на съвпадащи редове и намиране/замяна на съвпадащи низове или регулярни изрази.
Всеки път, когато извикате командата sed , цикълът на изпълнение се отнася до различни
опции, които са посочени и се изпълняват, докато се достигне краят на файла/входа. По-конкретно,
един цикъл на изпълнение изпълнява следните стъпки:
Командата sed изисква да посочите низ, който да съответства на редовете във файл. Да
предположим например, че файлът numbers.txt съдържа следните редове:
12
123
3 пет
4
123
3
Резултатът от предходната команда (всички редове между 123 и пет, включително) е тук:
123
3
Пет
x="abc" ехо
$x |sed "s/abc/def/"
деф
Резултатът е тук:
defabc
деф
деф
Machine Translated by Google
svcc.txt
четири пет
Резултатът е тук:
Резултатът е тук:
четири пет
Хулу
Спомнете си, че цялото число се състои от една или повече цифри, така че
съответства на регулярния израз [0-9]+, който съответства на една или повече цифри.
Трябва обаче да укажете регулярния израз [0-9]* , за да премахнете всяко число от
променливата x:
azAB xbcdw
Резултатът от предходната команда е тук (която работи само в един случай на abc):
ABC
Резултатът от предходната команда е тук (/g” означава, че работи във всеки случай на abc):
ABCdefABC
АбВГД
/cc/bb/aa/
за f в `ls *txt`
do
Списък 6.1 съдържа for цикъл, който обхожда списъка с текстови файлове със
суфикс txt . За всеки такъв файл инициализирайте променливата newfile , която се
създава чрез добавяне на низа _new към първия файл (представен от променливата
f). След това заменете срещанията на hello с низа goodbye във всеки файл f и
пренасочете изхода към $newfile. Накрая преименувайте $newfile на $f с помощта на
командата mv .
Ако искате да извършите актуализацията в съвпадащи файлове във всички
поддиректории, заменете командата for със следното:
1000|Джейн:Едуардс^Продажби
2000|Том:Смит^Разработка
3000|Дейв:Дел Рей^Маркетинг
Както можете да видите, вторият ред в листинг 6.3 е прост, но мощен: можете да разширите
командата sed с толкова разделители, колкото искате, за да създадете набор от данни с един
разделител между стойностите. Резултатът от листинг 6.3 е показан тук:
Този вид трансформация може да бъде опасна, освен ако не сте проверили дали вашият
нов разделител вече не се използва. За това е полезна команда grep (искате резултатът да е
нула):
sed -n 's/foo/bar/'
sed -n 's/foo/bar/p'
ABCnDEFnGHInJKLnMNOnPQRnSTUnVWXnYZ
Докато горният пример не изглежда особено полезен, помислете за голям текстов поток
без прекъсвания на редове (всичко на един ред). Можете да използвате нещо подобно, за да
вмъкнете знаци за нов ред, или нещо друго, за да разделите данните на по-лесни за обработка
части. Възможно е да работите с точно това, което прави sed , като разгледате всеки елемент
от командата и го сравните с изхода, дори ако не знаете синтаксиса. (Понякога ще срещнете
много сложни инструкции за sed без никаква документация в кода.)
Резултатът се променя след всеки три знака и знаем, че точката (.) съвпада с всеки
отделен знак, така че .{3} трябва да му казва да направи това (с екраниращи наклонени черти
(\)), защото скобите са специален знак за sed и няма да го интерпретира правилно, ако просто
го оставим като .{3}. n е достатъчно ясен в колоната за заместване, така че &\ трябва да му
казва да вмъкне знак, вместо да го замени. Командата g на терминала , разбира се, означава
„повтаряне“. За да изясните и потвърдите тези предположения, вземете това, което можете
да заключите, и извършете търсене в Интернет.
Отпечатване на
редове Списък 6.4 показва съдържанието на test4.txt (редове с двойно разстояние), които
се използват за няколко примера в този раздел.
абв
деф
Machine Translated by Google
абв
абв
абВ
ГДЕ
деф
абв
абв
абв
деф
деф
абв
абв
Machine Translated by Google
абв
абв
Следният кодов фрагмент отпечатва първите три реда и след това прави с главни букви
низа abc, дублирайки ABC в крайния изход, защото не използвахме -n и завършвахме с /p"
във втората команда sed . Не забравяйте, че /p" отпечатва само текст, който съответства на
командата sed , където основният изход отпечатва целия файл, поради което def не се
дублира:
ABC
ABC
деф
Можете също да използвате регулярни изрази със sed. Като напомняне, ето съдържанието на columns4.txt:
Следният кодов фрагмент илюстрира как да съпоставите редове, които съдържат малки
букви:
Machine Translated by Google
Следният кодов фрагмент илюстрира как да съпоставите редове, които съдържат числата
4, 5 или 6:
cat -t nocontrol1.txt
думи # uniq също показва броя на появяванията на всяка дума # Окончателното сортиране подрежда данните по броя на
думите.
аааа
Следната команда sed замества всички дублирани двойки букви с буквите aa:
аа/аа/аа/
1,234
По-общ sed израз, който може да вмъкне запетая в петцифрени числа, е тук:
12,345
'
ехо $x |tr -s ' '\н'
Резултатът е тук:
ghi
abc
Ghi
123
#def5
123z
'
ехо $x |tr -s ' '\n' |sed -nE "s/(^[a-zA-Z][a-zA-Z]*$)/\1/p"
Резултатът е тук:
ghi
abc
Ghi
Machine Translated by Google
Ако също така искате да сортирате изхода и да отпечатате само уникалните думи, прекарайте
резултатът от командите sort и uniq :
'
ехо $x |tr -s ' '\n' |sed -nE "s/(^[a-zA-Z][a-zA-
Z]*$)/\1/p"|сортирай|уник
Резултатът е тук:
Ghi
абв
ghi
'
echo $x |tr -s |sort|uniq ' '\n' |sed -nE "s/(^[0-9][0-9]*$)/\1/p"
Резултатът е тук:
123
'
ехо $x |tr -s ' '\n' |sed -nE "s/(^[0-9a-zA-Z][0-9a-zA-
Z]*$)/\1/p"|сортирай|уник
Резултатът е тук:
123
123z
Ghi
абв
ghi
Сега можете да замените echo $x с набор от данни, за да извлечете само азбучен ред
низове от този набор от данни.
Този раздел има за цел да покаже полезни проблеми, които можете да разрешите с един
ред на sed, и да ви изложи на още повече превключватели и аргументи, които можете да
смесвате и съчетавате, за да решавате свързани задачи.
Освен това sed поддържа други опции (които са извън обхвата на тази книга) за
изпълнение на много други задачи, някои от които са сложни и съответно сложни. Ако
срещнете нещо, което нито един от примерите в тази глава не покрива, но изглежда като
нещо, което sed може да направи, шансовете да го направи са добри. Търсене в интернет по
линия на „как да направя <xxx> в sed“ вероятно ще ви насочи в правилната посока или поне
към алтернативна команда bash, която ще бъде полезна.
здравей свят4
здравей свят5 две
здравей свят6 три
здравей свят4 четири
ред пет
ред шест
ред седми
Резултатът е тук:
здравей свят3
Резултатът е тук:
здравей свят4
Machine Translated by Google
Резултатът е тук:
ред седми
Резултатът е тук:
Резултатът е тук:
ред пет
ред шест ред
седем
Резултатът е тук:
здравей свят4
здравей свят4
Machine Translated by Google
Резултатът е тук:
ред пет
Резултатът е тук:
ред шест
ред седми
Резултатът е тук:
Резултатът е тук:
здравей свят4
здравей свят5 две
здравей свят6 три
ред седми
Резултатът е тук:
здравей свят4
здравей свят5 два реда седем
Резултатът е тук:
Резултатът е тук:
здравей свят4
здравей свят5 две
здравей свят6 три здравей свят6
три
Machine Translated by Google
ред шест
ред седми
Резултатът е тук:
здравей свят4
здравей свят6 три
ред пет ред
седем
Резултатът е тук:
,,n, ,,v,
,,n, s,x
,,n, s,v,n
Резултатът е тук:
,@#,@#,@#,@#o
wor,@#,@#4 ,@#,@#,@#,@#o wor,@#,@#5
две ,@#,@#, @#,@#o wor,@#,@#6 t,@#r,@#,@#
,@#,@#,@#,@#o wor,@#,@#4 ,@#нашите
,@#,@#n,@# ,@#,@#v,@# ,@#,@#n,@#
s,@#x ,@#,@#n,@#
s,@#v ,@#н
Machine Translated by Google
Резултатът е тук:
здравей свят4
здравей свят5 две
здравей свят6 три
здравей свят4 четири
ред пет
ред шест ред
седем
Резултатът е тук:
здравей свят4
helloworld5two
helloworld6three
helloworld4four linefive
линия шеста
линия седем
Резултатът е тук:
макаронени
изделия
макаронени
изделия
тестени
изделия паста
Вмъкнете два празни реда след третия ред и един празен ред след петия
ред в data4.txt с тази команда:
Резултатът е тук:
здравей свят4
здравей свят5 две
здравей свят6 три
ред шест
ред седми
Резултатът е тук:
здравей свят4
ред пет
ред шест
ред седми
Вмъкнете празен ред след всеки друг ред на data4.txt с тази команда:
Резултатът е тук:
Machine Translated by Google
здравей свят4
здравей свят5 две
ред седми
ред седми
ред шест
ред пет
здравей свят4 четири
здравей свят6 три
здравей свят5 две
здравей свят4
РЕЗЮМЕ
ГЛАВА 7
T
неговата глава ви запознава с командата awk , която е многофункционална програма
за манипулиране на данни и преструктуриране на набори от данни. Всъщност тази
помощна програма е толкова гъвкава, че са написани цели книги за помощната
програма awk . Awk е по същество цял програмен език в една команда, която приема
стандартен вход, дава стандартен изход и използва регулярни изрази и метасимволи по
същия начин, както другите команди на Unix. Това ви позволява да го включите в други
изрази и да правите почти всичко, с цената на добавяне на сложност към команден низ,
който може вече да прави доста неща.
Полезно е да добавите коментар, когато използвате awk, защото е толкова гъвкав, че
няма да е ясно коя от многото функции използвате с един поглед.
Първата част на тази глава предоставя кратко представяне на командата awk . Ще
научите за някои вградени променливи за awk и също как да манипулирате низови
променливи с помощта на awk. Обърнете внимание, че някои от тези примери,
свързани с низове, могат да се обработват и с помощта на други bash команди.
Втората част на тази глава ви показва условна логика, цикли while и for цикли в awk
за манипулиране на редовете и колоните в наборите от данни. Този раздел ви показва
как да изтривате редове и да обединявате редове в набори от данни, както и как да
отпечатвате съдържанието на файл като един ред текст. Ще видите как да „съединявате“
линии и групи от линии в набори от данни.
Третият раздел съдържа примерни кодове, които включват метасимволи (въведени
в Глава 1) и набори от знаци в awk команди. Ще видите също как да използвате условна
логика в awk команди, за да определите дали да отпечатате ред текст.
Machine Translated by Google
Четвъртият раздел илюстрира как да разделите текстов низ, който съдържа множество „.“
символи като разделител, последвани от примери за awk за извършване на числени изчисления
(като добавяне, изваждане, умножение и деление) във файлове, съдържащи числови данни. Този
раздел също ви показва различни цифрови функции, които са налични в awk, както и как да
отпечатате текст във фиксиран набор от колони.
Петият раздел обяснява как да подравните колони в набор от данни и как да подравните и
обедините колони в набор от данни. Ще видите как да изтривате колони, как да избирате поднабор
от колони от набор от данни и как да работите с многоредови записи в набори от данни. Този
раздел съдържа някои едноредови awk команди, които могат да бъдат полезни за манипулиране
КОМАНДАТА AWK
Като страничен коментар, има и командата gawk , която е GNU awk, както и командата nawk е
„нова“ awk (нито една команда не се обсъжда в тази книга). Едно предимство на nawk е, че ви
позволява да задавате външно стойността на вътрешна променлива.
Други вградени променливи включват FILENAME (името на файла, който awk чете в
момента), FNR (номерът на текущия запис в текущия файл), NF (броят на полетата в текущия
входен запис) и NR (номерът на входните записи, обработени от awk от началото на
изпълнението на програмата).
Консултирайте се с онлайн документацията за допълнителна информация относно
тези (и други) аргументи за командата awk .
Командата awk чете входните файлове един запис наведнъж (по подразбиране един
запис е един ред). Ако даден запис съвпада с шаблон, тогава се извършва действие (в
противен случай не се извършва действие). Ако шаблонът за търсене не е даден, тогава awk
изпълнява дадените действия за всеки запис на входа. Поведението по подразбиране, ако
не е дадено действие, е да се отпечатат всички записи, които отговарят на дадения шаблон.
И накрая, празните скоби без никакво действие не правят нищо; т.е. няма да изпълни
операцията за печат по подразбиране. Обърнете внимание, че всеки израз в действията
трябва да бъде разделен с точка и запетая.
За да направите предходния параграф по-ясен, ето няколко прости примера, включващи
текстови низове и командата awk (резултатите се показват след всеки кодов фрагмент).
Превключвателят -F задава разделителя на полето на всичко, което го следва, в този случай
интервал. Превключвателите често предоставят пряк път към действие, което обикновено
се нуждае от команда в блок BEGIN{} :
echo $x |awk -F" " '{print NF}' 5 echo $x |awk -F" " '{print $0}'
abcde
Machine Translated by Google
awk < test.txt '{ print $1 }' awk '{ print $1 }' <
test.txt awk '{ print $1 }' test.txt
Тук е показан още един начин (но както обсъдихме по-рано, може
бъдете неефективни, така че го правете само ако котката добавя стойност по някакъв начин):
Този прост пример за четири начина за извършване на една и съща задача трябва
да илюстрира защо включването на изрази за коментар в awk команди с всякаква
сложност е почти винаги добра идея. Имайте предвид, че следващият човек, който ще
разгледа вашия код, може да не знае, че е запознат с вашия стил на кодиране.
едно две
три четири
едно две три четири пет
шест
едно две три
четири пет
Machine Translated by Google
awk
{
# ляво подравняване $1 в колона от 10 знака
# дясно подравняване $2 в колона от 10 знака
# дясно подравняване $3 в колона от 10 знака
# дясно подравняване $4 в колона от 10 знака
printf("%-10s*%10s*%10s*%10s*\n", $1, $2, $3, $4)
}
' columns2.txt
Листинг 7.2 съдържа оператор printf() , който показва първите четири полета
на всеки ред във файла columns2.txt, където всяко поле е с ширина 10 знака.
Резултатът от стартирането на кода в листинг 7.2 е тук:
един * две* * *
три * четири* * *
четири * пет* * *
}
'
Изявлението while
x=0
while(x < 4) { print "x:",xx =
x+1
}
}
'
х:0
х:1
х:2
х:3
x = 0 do
{ print
"x:", xx = x + 1
} докато (x < 4)
}
'
х:0
х:1
х:2
х:3
Machine Translated by Google
}
}
КРАЙ { печат "\n" }
'
Листинг 7.3 съдържа for цикъл, който отпечатва числа на един и същ ред чрез
командата printf() . Забележете, че нов ред се отпечатва само в блока END на кода.
Резултатът от листинг 7.3 е тук:
01234
Следният кодов блок илюстрира как да използвате израз за прекъсване в for цикъл
в awk:
}
}
}
'
х:1
X:2
Следният кодов фрагмент илюстрира как да използвате next и продължите в for цикъл в awk:
awk
{
/израз1/ { var1 = 5; следващ } /израз2/ { var2 = 7;
next } /expression3/ { continue } // някой друг кодов
блок тук
Когато текущият ред съвпада с израз1, тогава на var1 се присвоява стойност 5 и awk
чете следващия входен ред; следователно израз2 и израз3 няма да бъдат тествани. Ако
израз1 не съвпада и израз2 съвпада , тогава на var2 се присвоява стойност 7 и след това
awk ще прочете следващия входен ред. Ако само израз3 води до положително съвпадение,
тогава awk пропуска оставащия блок код и обработва следващия входен ред.
a,b,c,de,f,g,h
1,2,3,4
5,6,7,8
inputfile="linepairs.csv"
outputfile="linepairsdeleted.csv"
Machine Translated by Google
awk ' NR%2 {printf "%s", $0; печат ""; следващ}' < $inputfile > $outputfile
Листинг 7.5 проверява дали текущият номер на запис NR се дели на 2, в който случай
отпечатва текущия ред и пропуска следващия ред в набора от данни. Изходът се
пренасочва към посочения изходен файл, чието съдържание е тук:
a,b,c,d 1,2,3,4
awk
{
if( NF == 2 ) { print $0 }
} ' columns.txt
Листинг 7.7 е ясен: ако текущият номер на запис е четен, тогава текущият ред се
отпечатва (т.е. редовете с нечетни номера се пропускат). Резултатът от стартирането на
кода в листинг 7.7 е тук:
едно две
Machine Translated by Google
едно три
едно четири
Ако искате да покажете редовете, които не съдържат 2 колони, използвайте следния кодов
фрагмент:
if( NF != 2 ) { print $0 }
абв
деф
абв
абв
Резултатът от предходния кодов фрагмент е тук. Вижте дали можете да кажете какво
се случва, преди да прочетете обяснението в следващия параграф:
Abcdefabcabc
Нашият разделител на записи по подразбиране за awk е /n (нов ред); това, което printf() прави, е
премахване на всички нови редове. Празните редове ще изчезнат напълно, тъй като всичко, което
имат, е новият ред, така че резултатът е, че всеки действителен текст ще бъде обединен без нищо
между тях. Ако бяхме добавили интервал между %s и крайната кавичка, щеше да има интервал между
всеки символен блок плюс допълнителен интервал за всеки нов ред.
Machine Translated by Google
# Обединяване на целия текст в един ред чрез премахване на новия ред awk '{printf("%s", $0)}' test4.txt
1
2
5
6
7
8
9
Листинг 7.9 отпечатва три последователни реда текст на един и същи ред, след което се отпечатва
нов ред. Това има ефект на „свързване“ на всеки три последователни реда текст. Резултатът от
стартирането на digits.sh е тук:
123
456
789
едно две
три четири
едно две три четири пет шест
едно две три
четири пет
awk
{
printf("%s",$0) if( $1 !~ /
one/) { print " " }
} ' columns2.txt
Забележете, че кодът в листинг 7.11 зависи от присъствието на низа „едно“ като първо
поле в редуващи се редове от текст - ние сливаме въз основа на съвпадение на прост
шаблон, вместо да го обвързваме с комбинации от записи.
За да обедините всяка двойка редове вместо сливане въз основа на съвпадение на
шаблон, използвайте модифицирания код в листинг 7.12.
awk
НАЧАЛО { брой = 0 } {
inputfile="linepairs.csv"
outputfile="linepairsjoined.csv" awk ' NR%2 {printf "%s,", $0;
следващ;}1' < $inputfile > $outputfile
един
пет
четири
awk
{
if( $0 ~ /^[0-9]/) { print $0 } if( $0 ~ /^[az]+ [0-9]/) { print $0 }
} ' columns3.txt
Следният кодов фрагмент отпечатва редовете текст в products.txt , чиято втора колона е по-голяма от 300:
Таблет нов
Използван таблет
Таблет нов
Използван таблет
'
ехо "05.20.144q.az.1.zip" | awk -F"." {
f5=$5 + 1
printf("%s.%s.%s.%s.%s.%s",$1,$2,$3,$4,f5,$6) }'
05.20.144q.az.2.zip
myFile="mixednumbers.txt"
линия = 0
}
КРАЙ { print "Total: ",total } ' $myfile
Резултатът от листинг 7.20 е тук. Вижте дали можете да разберете какво прави
кодът, преди да прочетете обяснението, което следва:
Общо: -3128
}'
Резултатът е тук:
Machine Translated by Google
3
4
-5
-5
}'
Резултатът е тук:
инф
1
6.14421e-06
Резултатът е тук:
2.48491 -инф
0
нан
печат cos(45);
}'
Резултатът е тук:
-0,448074
0,525322
Обърнете внимание, че rand започва да генерира числа от една и съща точка (или
„seed“) при всяко извикване на awk . Следователно програмата ще дава едни и същи
резултати при всяко стартиране. Ако искате една програма да прави различни неща всеки
път, когато се използва, трябва да промените семето на стойност, която ще бъде различна
при всяко изпълнение.
}'
Резултатът е тук:
нан
Кодовите фрагменти в този раздел препращат към текстовия файл short1.txt, който
можете да попълните с всякакви данни по ваш избор.
Следният кодов фрагмент отпечатва всеки ред, предшестван от броя на полетата във
всеки ред:
Отпечатайте първото и третото поле в обратен ред за редовете, които съдържат поне 3 полета:
awk '{if(NF > 2) print $3, $1}' short1.txt Отпечатва редовете, които
съдържат низа one: awk '{if(/one/) print }' *txt
Този раздел съдържа набор от кратки awk -базирани скриптове за извършване на различни
операции. Някои от тези скриптове могат да се използват и в други шел скриптове за извършване
на по-сложни операции. Списък 7.21 показва съдържанието на файла data.txt , който се използва в
различни примерни кодове в този раздел.
това е първи ред, който съдържа повече от 40 знака, това е втори ред
Предходният кодов фрагмент илюстрира лесен начин за изтриване на празни редове от файл
(или по-скоро за създаване на нов файл, подобен на стария файл, но от който празните редове са
премахнати).
Отпечатайте седем произволни числа от 0 до 100, включително:
Вмъкнете дубликат на всеки ред в текстов файл и също така премахнете празните редове:
awk '{print $0, "\n", $0}' < data.txt | awk 'NF > 0'
Поле 1: а
Поле 2: b
Поле 3: c
Поле 4: d
Поле 5: д
в,миналото,или,настоящето
за,миналото,или,настоящето
в,миналото,или,настоящето
за,поставянето,или,бъдещето в,миналото,
или,настоящето напълно,несвързано,ред1
в,миналото,или,настоящето
напълно,несвързано,ред2
в,миналото,или,настоящето,
напълно,несвързан,ред1
за,миналото,или,настоящето
Machine Translated by Google
напълно,несвързано,ред2
за,поставяне,или,бъдещето
в,миналото,или,настоящето
в,миналото,или,настоящето
напълно,несвързано,ред3
}' данни*.csv
Списък 7.25 търси срещания на миналия низ в колони 2, 5 и 7 поради следния кодов
фрагмент:
Ако възникне съвпадение, тогава стойността на броя се увеличава. Блокът END отчита броя пъти, в които
миналият низ е намерен в колони 2, 5 и 7. Имайте предвид, че низове като paste и pasted ще съвпадат с
миналия низ .
Резултатът от листинг 7.25 е тук:
}
}
}
'
aa bb cc
dd ee ff
gg hh
}
}
' VariableColumns.txt
това е линия
едно това е ред
номер едно това е
трети и последен
линия
Ако сте прочели предходните два примера, примерният код в този раздел е лесен за разбиране.
Ще научите как да подреждате отново колони с данни, които са правилни по отношение на тяхното
съдържание, но са поставени в различни редове (и следователно са неправилно подравнени). Списък
7.29 показва съдържанието на mixed-data.csv с неподравнени стойности на данните. В допълнение,
първият ред и последният ред в листинг 7.28 са празни редове, които ще бъдат премахнати от скрипта
на обвивката в този раздел.
inputfile="mixed-data.csv"
}
}' > временни колони
Листинг 7.30 започва с команда grep , която премахва празните редове, последвана
от команда awk , която отпечатва редовете на набора от данни като един ред текст.
Втората команда awk инициализира променливата columnCount със стойност 4 в
блока BEGIN , последвана от цикъл for в главния блок на кода за изпълнение, който
итерира през полетата за въвеждане. След като четири полета са отпечатани на един
и същи изходен ред, се отпечатва нов ред, което има ефект на преподреждане на
входния набор от данни като изходен набор от данни, състоящ се от редове, които
имат четири полета. Резултатът от листинг 7.30 е тук:
“”}
}
}' > временни колони
Списък 7.33 е много подобен на листинг 7.30. Основната идея е да се отпечата символ за подаване на
ред, след като двойка „нормални“ записи са били обработени, което е имплементирано чрез кода, показан с
Сега можете да обобщите листинг 7.33 много лесно, като промените първоначалната
стойност на променливата rowCount на всяко друго положително цяло число и кодът ще
работи правилно без допълнителни модификации. Например, ако инициализирате rowCount
на стойност 5, тогава всеки ред в новия набор от данни (с възможното изключение на
крайния изходен ред) ще съдържа 5 „нормални“ записа с данни.
awk '{ for (i=2; i<=NF; i++) printf "%s ", $i; printf "\n"; }' products.txt
Цикълът е между 2 и NF, който итерира всички полета с изключение на първото поле.
В допълнение, printf() изрично добавя нови редове. Резултатът от предходния кодов
фрагмент е тук:
400 нови
300 нови
300 използвани
200 използвани
100 използвани
Сара, 1000
Дейв, 3000
Дейв, 5000
Тони, 7000
inputfile="mixed-data.txt"
Списък 7.37 съдържа нов блок код, който пренасочва изхода от Стъпка #4 към
временен файл temp-columns2, чието съдържание се обработва от друга awk команда
в последния раздел на Списък 7.37. Забележете, че командата awk съдържа блок
BEGIN , който инициализира променливите rowCount и currRow със стойностите
съответно 2 и 0.
Основният блок отпечатва колони 1 и 3 от текущия ред, ако номерът на текущия
ред е четен, след което стойността на currRow се увеличава. Резултатът от тази команда
awk се пренасочва към още един временен файл, който е вход за крайния кодов
фрагмент, който използва командата cat и две повторения на командата sed за
премахване на завършващ „,“ и завършващ интервал, както е показано тук :
awk
# Отпечатайте списък с честоти на думите {
}
КРАЙ
{ за (дума в честота) printf "%s\t%d\n",
дума, честота[дума]
} ' columns2.txt
Листинг 7.38 съдържа блок от код, който обработва редовете в columns2.txt. Всеки
път, когато се срещне дума (от ред), кодът увеличава броя на срещанията на тази дума
в хеш таблицата freq.
Machine Translated by Google
Блокът END съдържа for цикъл, който показва броя на срещанията на всяка дума в
columns2.txt.
Резултатът от листинг 7.38 е тук:
две
един
3 3 три 3
шест 1
четири 3
пет 2
Списък 7.39 показва съдържанието на WordCounts2.sh , който извършва преброяване на думи без
значение от главни и малки букви.
awk
{
# преобразувайте всичко в малки букви $0 = tolower($0) #
премахнете пунктуацията
#gsub(/[^[:alnum:]_[:blank:]]/, "", $0)
}
}
КРАЙ
{ for(word in freq) {
printf "%s\t%d\n", дума, честота[дума]
}
} ' columns4.txt
Списък 7.39 започва с кодов фрагмент, който преобразува текста във всеки входен
ред в малки букви, както е показано тук:
$0 = по-ниско ($0)
456 1
две 3
един 3
три 3
шест 1
123 2
четири 3
пет 2
}
'
| сортиране | уникално
ехо
'
ехо $x |tr -s ' '\н'
Резултатът е тук:
ghi
abc
Ghi
123
#def5
123z
Резултатът е тук:
ghi
abc
Ghi
И накрая, ако искате също да сортирате изхода и да отпечатате само уникалните думи,
пренасочете изхода от командата awk към командата за сортиране и командата uniq .
Machine Translated by Google
Втората awk команда използва регулярния израз ^[0-9]+ за проверка за цели числа,
а третата awk команда използва регулярния израз ^[0-9a-zA-Z]+ за проверка за буквено-
цифрови думи. Резултатът от стартирането на листинг 7.37 е тук:
Само думи:
Ghi
abc
ghi
Ghi
абв
ghi
EmpId: 12345
Адрес: 123 Main Street Чикаго Илинойс
EmpID: 23456
Адрес: 432 Lombard Avenue SF Калифорния
inputfile="employees.txt" outputfile="employees2.txt"
Machine Translated by Google
awk
{
if($0 ~ /^Име:/) {
x = substr($0,8) ","
следващия
if( $0 ~ /^Empid:/) {
#пропускане на реда с данни на
Empid #x = x substr($0,7) ","
следващия
if($0 ~ /^Address:/) { x = x
substr($0,9) print x
}
}
'
< $inputfile > $outputfile
Сега, след като сте видели изобилие от awk кодови фрагменти и shell скриптове, съдържащи
командата awk , които илюстрират различни типове задачи, които можете да изпълнявате върху
файлове и набори от данни, вие сте готови за някои случаи на употреба. Следващият раздел
(който е първият случай на употреба) ви показва как да замените няколко разделителя на
полета с един разделител, а вторият случай на употреба ви показва как да манипулирате низове
с дата.
Примерният код в този раздел ви показва как да използвате командата awk , за да разделите
полетата, разделени със запетая, в редовете на набор от данни, където полетата могат да
съдържат вложени кавички с произволна дълбочина.
Листинг 7.44 показва съдържанието на файла quotes3.csv , който съдържа разделител „,“ и
множество полета в кавички.
field5,field4,field3,"field2,foo,bar",field1,field6,field7,"fieldZ"
Machine Translated by Google
fname1,"fname2,други,неща",fname3,"fname4,foo,bar",fname5
"lname1,a,b","lname2,c,d","lname3,e,f","lname4,foo, бар", име5
#inputfile="quotes1.csv"
#inputfile="quotes2.csv"
inputfile="quotes3.csv" grep -v "^$"
$inputfile | awk ' {
РЕД #1:
поле5,поле4,поле3,"поле2,foo,лента",поле1,поле6,поле7,"полеZ"
------------------------
поле #1 : поле5 поле #2 :
поле4 поле #3 : поле3 поле
#4 : "поле2,foo,bar" поле
#5 : поле1 поле #6 : поле6 поле #7 : поле7
поле #8 : "полеZ"
РЕД #3:
"lname1,a,b","lname2,c,d","lname3,e,f","lname4,foo,bar",lname5
------------------------
поле #1 : "Външно1 "Вътрешно "Вътрешно "Вътрешно C" B" A" Външно1" поле #2 : "XYZ1,c,d"
поле #3 : "XYZ2lname3,e,f"
РЕД #5:
------------------------
Както можете да видите, задачата в този раздел се решава лесно чрез командата awk .
inputfile="dates2.csv"
outputfile="formatteddates2.csv"
-d"," -f1` lname=`echo $line |cut -d"," -f2` date1=`echo $line |cut -
d"," -f3`
РЕЗЮМЕ
awk за манипулиране на редовете и колоните в наборите от данни. След това видяхте как да изтривате редове и
да обединявате редове в набори от данни, както и как да отпечатвате съдържанието на файл като един ред текст.
След това научихте как да използвате метасимволи и набори от знаци в awk команди. Научихте как да извършвате
числени изчисления (като добавяне, изваждане, умножение и деление) във файлове, съдържащи числови данни,
ГЛАВА 8
неговата глава ви запознава със скриптове на shell, които илюстрират как да решавате
T grep команда,
някои така чезадачи. Някои примери разчитат на това
добре познати
би било подходящо време да прегледате материала в главата, която съдържа
информация, свързана с grep. По-късно в тази глава ще видите шел скриптове, които
включват базирани на рекурсия алгоритми за добре познати задачи като най-големия
общ делител (НОД) и най-малкото общо кратно (НКМ) на две положителни цели числа.
Първата част на тази глава започва с примери за прости шел скриптове и как да
направите тези шел скриптове изпълними. Този раздел също така ви показва как да
„извлечете“ или „точка“ скрипт на обвивка и описва ситуации, когато е необходимо да се
направи това.
Втората част на тази глава ви показва как да използвате параметри за предаване на
функции на обвивка, които са дефинирани в скриптове на обвивка, да определите броя на
стойностите, предадени на функция, и да покажете техните стойности. Този раздел също
така съдържа пример за интерактивен shell скрипт (т.е. подканва потребителите да
въвеждат).
Третата част на тази глава ви показва как да използвате рекурсия, за да изчислите
стойността на факториела на положително цяло число. В допълнение, този раздел ви
показва скриптове на обвивката за изчисляване на числата на Фибоначи, GCD и LCM на
две положителни цели числа и делителите на положително цяло число.
Machine Translated by Google
Въпреки че някои от примерите може да нямат незабавна стойност за вас, все пак си струва да
отделите време да ги прочетете, за да видите дали съдържат техники, които можете да използвате във
вашите собствени скриптове на обвивката.
Скриптовете на Shell могат да съдържат всички команди bash, налични във вашата система, но
някои команди изискват командата sudo , която от своя страна изисква парола. Простите примери за
скриптове на обвивката включват команди, свързани с файлове, които създават файлове, четат данни
от файлове и актуализират съдържанието на файловете. Независимо от съдържанието на вашите шел
скриптове, те се интерпретират „в движение“, така че няма стъпки за компилиране, които създават
двоичен изпълним файл.
Shell скриптовете автоматизират процеса на изпълнение на набор от bash команди, така че да не
е необходимо да ги изпълнявате ръчно от командния ред. Ако трябва да изпълните проста команда от
командния ред, тогава е малко вероятно да трябва да го направите чрез шел скрипт: просто въведете
командата и натиснете клавиша <RETURN> . Обърнете внимание, че помощната програма bash crontab
ви позволява да планирате изпълнението на shell скриптове на регулярна основа (почасово, ежедневно,
седмично и т.н.). Глава 10 предоставя допълнителна информация относно помощната програма
crontab .
ви показва как да създадете шел скрипт, който съдържа набор от прости команди, които се
изпълняват последователно. По-конкретно, създайте текстовия файл test.sh (използвайки любимия си
текстов редактор) със следното съдържание:
#!/bin/bash pwd ls
cd /
tmp
Machine Translated by Google
ls
chmod +x test.sh
./test.sh
Първият ред в test.sh се нарича ред "shebang", който насочва системата да стартира
bash shell, за да извика командите в test.sh. Терминът "shebang" е нещо като смесване
на думите "hash" (за знака "#") и "bang" (за знака "!"). Обърнете внимание, че началният
“./” на ./test.sh указва файла test.sh в текущата директория: ако файлът test.sh е във
вашата домашна директория, посочете $HOME/test.sh. Освен това, ако „.“ е включена в
променливата на средата PATH , тогава можете просто да въведете test.sh без префикса
“./” .
Една точка относно командата mkdir : ако посочите път, в който не съществуват
междинни директории, тогава трябва да използвате превключвателя. Например,
-стр ако
директорията /tmp/abc не съществува, следната команда изисква
-стр превключвател:
mkdir -p /tmp/abc/def
Уверете се, че abc.sh е изпълним shell скрипт с командата chmod (както е показано
по-рано в тази глава) и след това стартирайте следната последователност от команди от
командния ред:
експортиране x="tom"
echo "x = $x" ./abc.sh
echo "x = $x"
x = том
вътре в abc.sh x = 123
x = том
x = "том смит"
вътре abc.sh
x = 123 x
= 123
функция fname() {
изявления;
}
fname() {
изявления;
}
Функция на обвивката може да бъде извикана от нейното име, както е показано тук:
#!/bin/sh
функция1 () {
функция2 () {
вътрешна функция 1
#!/bin/sh
функция1 () {
функция1 а
функция1 аб
функция1 abc
в началото на функция 1
параметър 1: a
параметър
2: параметър
3: в началото на функция
1 параметър 1:
a параметър 2:
b параметър
3: в началото на функция
1 параметър 1:
a параметър 2:
b параметър 3: c
#!/bin/sh
функция1 ()
Machine Translated by Google
{
echo "брой параметри: $#" echo "всички
параметри: $@" echo ""
функция1 abc
функция1 abcd функция1 1 2 3 4
5
show_args ()
Machine Translated by Google
{
echo "Брой аргументи: $#" echo "Име на
скрипт: $0" echo "Първи аргумент: $1" echo
"Втори аргумент: $2" echo "Трети аргумент:
$3" echo "Всички аргументи: $@"
#!/bin/sh
Стойност на i: 1
Стойност на i: 2
Стойност на i: 3
Стойност на i: 4
Стойност на i: 5
#!/bin/sh
iterate() {
за arg
итерация abcde
стойност: а
стойност: b
стойност: c
стойност: d
стойност: e
#!/bin/sh
iterate() {
iterate() {
arg1="$1"; смяна;
за arg
итерация abcde
Machine Translated by Google
Както можете да видите, функцията в листинг 8.7 итерира стойностите, които се предават на
функцията iterate(). Има обаче две дефиниции на функцията iterate() и правилото е просто:
последната (най-долната) дефиниция се изпълнява и всички други дефиниции се игнорират
(може да има повече от две дефиниции на една и съща функция).
Друга подробност, която трябва да забележите, е първият кодов фрагмент, който е показан с удебелен шрифт
arg1="$1"; смяна;
стойност: b
стойност: c
стойност: d
стойност: e
#!/bin/sh
iterate() {
for (( i=2; i <= "$#"; i++ )) do echo "arg position: ${i}" ${!i}"
итерация abcde
Както можете да видите, функцията в листинг 8.8 итерира стойностите, които се предават на
функцията iterate(). Цикълът for обаче започва от
Machine Translated by Google
позиция на аргумент: 2
стойност на аргумент: b
позиция на аргумент: 3
стойност на °С
аргумент: позиция на
аргумент: 4 стойност на
аргумент: d позиция на
д
аргумент: 5 стойност на аргумент:
#!/bin/sh
iterate() {
Брой аргументи: 4
Списък с аргументи: abcdef
аргумент: a аргумент:
bc
Machine Translated by Google
аргумент: d аргумент:
еф
нула" fi
esac
./PositionalParameters1.sh да 2 3 4
съвпадения
#!/bin/bash
функция checkNewUser() {
if test "$1" = "John" && test "$2" = "Smith" then return 1 else
върнете 0
фи
}
Machine Translated by Google
"
/bin/echo -n "Собствено име: прочетете fname /
bin/echo -n
"
"Фамилно име: прочетете lname
#!/bin/sh echo
"Как се казваш?" read PERSON echo "Здравей,
$PERSON"
$./test.sh Как се
казвате?
Джон Смит
#!/bin/sh
факториал() {
else #
стигнахме до 1: echo 1
фи
}
Листинг 8.12 съдържа функцията factorial() с условна логика: ако първият параметър
е по-голям от 1, тогава променливата decr се инициализира като 1 по-малко от стойността
на $1, последвано от инициализиране на резултата с рекурсивно извикване на функцията
factorial() с аргумент обв. И накрая, този блок код инициализира продукта като стойност
от $1 , умножена по стойността на резултата. Имайте предвид, че ако първият параметър
не е по-голям от 1, тогава се връща стойност 1.
Въведете номер:
7 7! = 5040
#!/bin/bash
факториал() {
num=$1
резултат=1
Machine Translated by Google
ехо $резултат
}
Въведете число: 8
8! = 40320
#!/bin/bash
факториал() {
num=$1
резултат=1 за
(( i=2; i<=${num}; i++ )); направете резултат=$((${резултат}
*$i))
Machine Translated by Google
factvalues[$i]=$готов резултат
факториел $num
" ${factvalues[$i]}
Въведете число: 9
Факториал на 1: 1
Факториал на 2: 2
Факториел от 3 : 6
Факториел от 4:24
Факториел от 5:120
Факториел от 6 : 720
Факториел от 7 : 5040
Факториел от 8 : 40320
Факториел от 9: 362880
#!/bin/sh
LOGFILE="/tmp/a1" rm -f $LOGFILE
2>/dev/null fib() {
друго
ехо 1 фи
фи
}
Списък 8.15 съдържа код, който намалява две променливи, наречени decr1 и
decr2, за да направи рекурсивни извиквания на функцията fib() , докато изчисляването
на факторните стойности включва намаляване само на една променлива.
Освен това листинг 8.15 съдържа кодов фрагмент, който записва междинни
изчисления в текстов файл, който след това можете да прегледате, за да проследите
пътя на изпълнение на кода. Стартирайте кода в листинг 8.15 и ще видите следния
резултат:
Въведете число: 10
фибоначи 10 = 55
#!/bin/sh
функция gcd() {
$remainder` fi
фи
}
a="4"
b="20"
a="4"
b="22"
a="20"
b="3"
a="10"
b="10"
НОД на 4 и 20 = 4
НОД на 22 и 4 = 2
НОД на 3 и 20 = 1
НОД на 10 и 10 = 10
Листинг 8.17 показва съдържанието на шел скрипта lcm.sh , който изчислява LCM
на две положителни цели числа. Този скрипт съдържа кода в скрипта на обвивката
gcd.sh за изчисляване на LCM на две положителни цели числа.
#!/bin/sh
функция gcd() {
if [ $remainder == 0 ]
Machine Translated by Google
then
echo $2 else
фи
}
функция lcm() {
a="24"
b="10"
result=`lcm $a $b` echo "LCM
на $a и $b = $result"
a="10"
b="30"
result=`lcm $a $b` echo "LCM
на $a и $b = $result"
LCM от 24 и 10 = 120
LCM от 10 и 30 = 30
#!/bin/sh
Machine Translated by Google
функция divisors() {
div="2"
num="$1"
прости числа=""
while (true) do
фи
Свършен
num="12"
num="768"
num="12345"
num="23768"
Списък 8.18 съдържа функцията divisors() , която се състои основно от цикъл while ,
който проверява за делителите на num (което се инициализира като стойност $1).
Първоначалната стойност на div е 2 и всеки път, когато div дели, стойността наброй,
div се
добавя към низа с прости числа и num се заменя с
Machine Translated by Google
РЕЗЮМЕ
ГЛАВА 9
T
неговата глава съдържа набор от bash скриптове, които илюстрират как да
решаване на някои добре познати задачи. Моля, уверете се, че сте прочели предишната
глава, отнасяща се до командата, ако още не сте го направили.
grep
Първата част на тази глава ви показва набор от bash скриптове, които използват awk
за изпълнение на различни задачи, като например конвертиране на многоредови записи в
едноредови записи. Ще научите също как да изчислявате общата сума на всеки ред в набор
от данни.
КОМАНДАТА GREP
Първият пример в този раздел илюстрира как да определите кои zip файлове съдържат
SVG документи. Вторият пример в този раздел ви показва как да проверявате записите в
регистрационен файл (със симулирани стойности). Третият примерен код ви показва как да
използвате командата за симулиране на релация
grep
Machine Translated by Google
намерен списък=""
notfoundlist=""
Свършен
Листинг 9.1 търси zip файлове за твърдо кодирания низ svg: ръчно заменете този
низ с всеки път, когато искате да търсите набор от zip файлове за различен низ. Като
алтернатива можете да подканите потребителите за низ за търсене, така че да не е
необходимо да правите ръчни промени в скрипта на обвивката.
За ваше удобство листинг 9.2 показва съдържанието на searchstrings.sh , което
илюстрира как да въведете един или повече низове в командния ред, за да търсите
тези низове в zip файловете в текущата директория.
намерен списък=""
notfoundlist=""
Machine Translated by Google
<string-list>" изход
фи
фи
notfoundlist="$f ${notfoundlist}" fi
Свършен
Списък 9.2 първо проверява дали поне един файл е указан в командния
ред и след това инициализира променливата zipfiles със списъка на zip
файловете в текущата директория. Ако zipfiles е null, се показва подходящо съобщение.
Следващият раздел на листинг 9.2 съдържа for цикъл, който обработва
всеки аргумент, зададен в командния ред. За всеки такъв аргумент друг for
цикъл проверява имената на zip файловете, които съдържат този аргумент. Ако
има съвпадение, тогава променливата $foundlist се актуализира, в противен
случай се актуализира променливата $notfoundlist . Когато вътрешният цикъл приключи,
Machine Translated by Google
Ако имате Java SDK на вашата машина, можете също да използвате командата jar
вместо командата за разархивиране , както е показано тук:
SKUVALUES="skuvalues.txt"
SKUSOLD="skusold.txt"
Machine Translated by Google
Списък 9.3 съдържа for цикъл, който обикаля редовете на файла skuvalues.txt и
предава тези SKU стойности, една по една, на команда, която включва командите cat,
grep и awk . Целта на последната комбинация от команди е да изпълни следното:
7200 6.25
8000 3,50
SKUVALUES="skuvalues.txt"
Machine Translated by Google
SKUSOLD="skusold.txt"
SKUPRICES="skuprices.txt"
$sku $SKUPRICES | cut -d" " -f2' subtotal=`cat $SKUSOLD |grep $sku | awk '{общо += $2}
SKUVALUES="skuvalues.txt"
SKUSOLD="skusold.txt"
############################## #изчисляване на
общите суми за всяка sku ###############
################ за sku в `cat $SKUVALUES` do total=`cat
$SKUSOLD |grep $sku | awk '{total += $2} END {print
total}'` echo "ПРОДАДЕНИ ЕДИНИЦИ ЗА SKU $sku: $total" echo "$sku|$total" >> $TOTALS готово
Machine Translated by Google
########################## #изчислете
макс./мин./средно ##################
######### awk -F"|" '
}
КРАЙ {print "Minimum = ",min print "Maximum =
",max print "Average = ",avg print "Total
= ",сума
}
$ TOTALS
Списък 9.6 инициализира някои променливи, последвани от for цикъл, който извиква
awk команда за изчисляване на междинни суми (т.е. брой продадени единици) за всяка SKU
стойност. Следващата част от листинг 9.6 съдържа команда awk , която изчислява максимума,
минимума, средната стойност и сумата за SKU единиците във файловете $TOTALS.
C1000,"Радио",54.99,2,"01/22/2013"
C1000,"DVD",15.99,5,"01/25/2013"
C2000,"Лаптоп",650.00,1,"01/24/2013"
C3000,"Мобилен телефон",150.00,2,"01/28/2013"
ехо
Свършен
Клиент C1000:
Подробности за клиента: C1000 John Smith LosAltos California 94002 Поръчки за покупка:
C1000,"Radio",54.99,2,"01/22/2013"
C1000,"DVD",15.99,5,"01/25/2013"
----------------------
----------------------
Клиент C3000:
Подробности за клиента: C3000 Billy Jones HalfMoonBay Калифорния 94040 Поръчки за покупка:
C3000,"CellPhone",150.00,2,"01/28/2013"
----------------------
DataFile="mylogfile.txt"
OK="добре"
ERROR="грешка"
sleeptime="2" loopcount=0
lastline=`tail -1 $DataFile`
else
newline="`date` СИСТЕМНА ГРЕШКА"
fi
echo $newline >> $DataFile
elif [ "$badstatus" != "" ] then echo "Грешка в
фи
Свършен
Листинг 9.11 инициализира някои променливи и след това гарантира, че лог файлът mylogfile.txt
е празен. След добавяне на начален ред към този журнален файл, цикълът while периодично заспива
и след това проверява съдържанието на последния ред текст в журналния файл. Към този лог файл се
добавят нови текстови редове и когато се открие съобщение за грешка, кодът излиза от цикъла while .
Примерно извикване на листинг 9.11 е тук:
Грешка в регистрационния файл: четвъртък, 23 ноември, 18:22:22 PST 2017 СИСТЕМНА ГРЕШКА
Листинг 9.12 показва съдържанието на набора от данни multiline.txt. Списък 9.13 показва
съдържанието на шел скрипта multiline.sh , който комбинира множество редове в един запис.
Machine Translated by Google
Мери Смит
999 Апиев път
Римски град, SF 94234
Джейн Адамс
Главна улица 123
Чикаго, IL 67840
Джон Джоунс
321 Pine Road
Навсякъде, MN 94949
Имайте предвид, че всеки запис обхваща няколко реда, които могат да съдържат бели
интервали, и записите са разделени с празен ред.
""
НАЧАЛО { RS = { ; FS = "\n" }
} ' multiline.txt
12345
6 7 8 9 10
55555
15
40
25
# изискван изход:
#xyz3:77774:XYZ123
#xyz3:84362:WASH7P
} ' genetics.txt
Списък 9.17 съвпада с входни редове, чието трето поле е равно на gen, след
което триплетът на масива се попълва с компонентите на шестото поле, като се
използват знаците „;“ и “=” като разделители в шестото поле. Резултатът се състои от
първото поле, четвъртото поле и втория елемент в триплета на масива. Резултатът
от стартирането на листинг 9.17 е тук:
xyz3:77774:XYZ123
xyz3:84362:WASH7P
1,1,1,1,1
5,4,3,2,1
8,8,1,8,8
5,4,3,2,1
1,6,6,7,7
Machine Translated by Google
# В блока END (или последния ред на файла) # това е броят на редовете във файла.
# Решение в R: https://gist.github.com/dsparks/3693115
НАЧАЛО {сума = 0} {
НАЧАЛО {сума = 0} {
за (i=0; i<=NF; i++) { if(NR >= 1 && i+NR == NF+1) { сума += $i; } } }
Списък 9.19 започва с команда awk , която съдържа цикъл, който съответства
на „диагонални“ елементи на набора от данни, което ще рече първото поле на
първия запис, второто поле на втория запис, третото поле на третия запис и така
нататък. Този процес на съвпадение се управлява от условната логика вътре в
цикъла for .
Втората част на списък 9.19 съдържа команда awk , която отпечатва
недиагонални елементи на набора от данни, като се използва проста инструкция за печат .
Третата част на листинг 9.19 съдържа awk команда, която съдържа същата
логика като първата awk команда и след това изчислява кумулативната сума на
диагоналните елементи.
Machine Translated by Google
Главен диагонал:
41
2
7
Извън диагонала: 1
2
1
41
1,0.10,53,15
2,0.12,54,16
3,0.19,65,10
4,0.25,86,23
5,0.18,57,17
6,0.23,79,34
7,0.34,66,21
1,0.00,63,24
2,0.02,64,25
3,0.09,75,19
Machine Translated by Google
4,0.15,66,28
5,0.08,67,36
6,0.13,79,23
7,0.24,68,25
1,1.00,83,34
2,0.02,84,35
3,1.09,75,19
4,0.15,86,38
5,1.08,87,36
6,0.13,79,33
7,0.24,88,45
инча+=$2
градуса+=$3
влажност+=$4
}
КРАЙ
{ printf("ИМЕ НА ФАЙЛ: %s\n", ИМЕ НА ФАЙЛ) printf("инчове:
%.2f\n", инчове/7) printf("градуси: %.2f\n", градуси/7) printf(" влажност:
%.2f\n", влажност/7)
} ' дъжд?.csv
Machine Translated by Google
Листинг 9.23 изчислява сумата от числата в три колони (т.е. инчове валежи,
градуси по Фаренхайт и влажност като процент) в наборите от данни, определени от
израза rain?.csv, който в този конкретен пример се състои от наборите от данни rain1.
csv, rain2.csv и rain3.csv.
По този начин листинг 9.23 може да обработва множество набори от данни
(rain1.csv до rain9.csv). Можете да обобщите този пример, за да обработвате всеки
набор от данни, който започва с низа rain и завършва с наставката csv със следния
израз:
дъжд*.csv
ИМЕНА НА ФАЙЛОВЕ:
mon_rain[FNR]+=$2
mon_degrees[FNR]+=$3
mon_humidity[FNR]+=$4 idx[FNR]++
}
END
{ printf("ДЕН ИНЧОВ ГРАДУСИ ВЛАЖНОСТ\n")
Machine Translated by Google
i,mon_rain[i]/idx[i],mon_degrees[i]/idx[i],mon_humidity[i]/idx[i])
}
} ' дъжд?.csv
1,0.10,53,15 2,0.12,54,16
3,0.19,65,10 4,0.25,86,23
5,0.18,57,17 6,0.23,79,34
7,0.34,66,21
1,0.00,63,24
2,0.02,64,25 3,0.09,75,19
4,0.15,66,28 5,0.08,67,36
6,0.13,79,23 7,0.24,68,25
Machine Translated by Google
1,1.00,83,34
2,0.02,84,35
3,1.09,75,19
4,0.15,86,38
5,1.08,87,36
6,0.13,79,33 7,0.24,88,45
# посочете списъка с CSV файлове (поддържа множество регулярни изрази) files=`ls rain*csv zain*csv`
mon_rain[FNR]+=$2
mon_degrees[FNR]+=$3
mon_humidity[FNR]+=$4 idx[FNR]++
}
END
{ printf("ДЕН ИНЧОВ ГРАДУСИ ВЛАЖНОСТ\n")
i,mon_rain[i]/idx[i],mon_degrees[i]/idx[i],mon_humidity[i]/idx[i])
}
Списък 9.28 извършва същите изчисления като листинг 9.24, със следната вариация:
наборите от данни, определени от променливите файлове , които се дефинират от
регулярния израз 'ls rain*csv zain*csv'. Можете да модифицирате този регулярен израз,
за да включи всеки списък с файлове, които трябва да бъдат обработени.
Забележете, че последният ред код в листинг 9.28 използва заместване с обратна
отметка, за да разшири регулярния израз в дефиницията на променливите файлове:
Като още един вариант, можете да посочите файл (да го наречем filelist.txt) , който
съдържа списък с имена на файлове, които искате да обработите, и след това да
замените предходния ред, както следва:
$2 += $3 * 2 + $4 / 2 $3 += $4 / 3 + $2 *
$2 / 10 $4 += $2 + $3 $1 += $2 * 3 - $4 / 10
Machine Translated by Google
printf("%d,%.2f,%.2f,%.2f\n",$1,$2,$3,$4)
} ' дъжд?.csv
194,113.60,1348.50,1477.10
196,116.12,1407.72,1539.84
204,135.19,1895.97,2041.16
187,183.75,3470.07,3676.82 202,122.68,1567
.70,1707.38 194,175.23,3160.89,3370.12
207,142.84,2113.33,2277.17
201,138.00,1975.40,2137.40
202,140.52,2046.92,2212.44 201,1 59.59,
2628.23, 2806.82 203,146.15,2211.32,2385.47
203,152.08,2391.83,2579.91
199,169.63,2964.10,3156.73
206,148.74,2288.69,2462.43 183,184.00,3479
.93,3697.93 182,185.52,3537.43,3757.95
200,160.59,2660.25,2839.84
179,191.15,3752.50,3981.65
178,193.08,3826.99,4056.07 195,1 74.63,
3139.56, 3347.19 173,198.74,4052.76,4296.50
РЕЗЮМЕ
Machine Translated by Google
В тази глава видяхте примери как да създадете някои полезни bash команди. Първо
видяхте bash скрипт за работа с текстови файлове, съдържащи многоредови записи. След
това видяхте как да изчислявате кумулативни суми на числови полета в записите. След
това научихте как да използвате функцията split() вътре в shell скрипт с команда awk .
ГЛАВА 10
T
неговата глава съдържа еклектичен асортимент от bash скриптове, които илюстрират
как да изпълнявате различни задачи, включващи множество файлове и директории,
работа с компресирани файлове, фонови процеси и отпечатване на прости отчети.
ИЗПОЛЗВАНЕ НА RM И MV С ДИРЕКТОРИИ
rm -r моите_неща
Machine Translated by Google
mv my_stuff /tmp
cp -r my_stuff my_stuff2
myfiles/wordfiles/chapter1/chapter1.doc myfiles/wordfiles/chapter2/
chapter2.doc myfiles/wordfiles/chapter3/chapter3.doc myfiles/
wordfiles/chapter4/chapter4.doc myfiles/wordfiles/chapter1/data1.txt
myfiles/wordfiles/chapter2 /data2.txt myfiles/wordfiles/chapter3/
data3.txt myfiles/wordfiles/chapter4/data4.txt
Листинг 10.1 показва съдържанието на shell скрипта maketree.sh , който създава набор от
поддиректории в текущата директория.
# премахнете myfiles rm -r
myfiles 2>/dev/null
докоснете myfiles/wordfiles/chapter3/chapter3.doc
докоснете myfiles/wordfiles/chapter4/chapter4.doc
докоснете myfiles/wordfiles/chapter1/data1.txt
докоснете myfiles/wordfiles/chapter2/data2.txt
докоснете myfiles/wordfiles/chapter3/data3.txt
докоснете myfiles/wordfiles/chapter4/data4.txt
#################################################### # # Дефиниране
на променлива със списък с имена на директории # Този метод не зависи от
външен файл.
# Алтернативно, поставете тези имена в текстов файл # и след това прочетете
съдържанието на този текстов файл.
#################################################### #
if [ then ! -d $mydir]
mkdir
$mydir cd $mydir
echo "създаване на директория $name в $mydir" mkdir $name done else echo
"Директория $mydir
съществува" fi
Въпреки това, ако извикате кода в листинг 10.2 втори път, ще го направите
вижте следния изход:
Джон-Смит Джейн-
Смит Дейв-Джоунс
Андрю-Уебър
кийт-томпсън
if [ then ! -d имена2]
echo
фи
cd имена2
Въпреки това, ако извикате кода в листинг 10.4 втори път, ще го направите
вижте множество грешки, тъй като директориите вече съществуват, както е показано тук:
ако ! -d имена2]
[ тогава
фи
cd имена2
"Директория $d вече
Свършен
Списък 10.5 съдържа прост for цикъл, който обикаля съдържанието на имената на
директориите (сродници). Кодовият блок if /else проверява дали
Machine Translated by Google
if [ then ! -d имена2]
echo
фи
cd names2 echo
Свършен
Списък 10.6 съдържа прост for цикъл, който обикаля съдържанието на имената
на директориите (сродници). Кодовият блок if /else проверява дали
Machine Translated by Google
директорията вече съществува; ако е така, се показва съобщение; ако не, директорията
се създава в директорията names2 .
Стартирайте кода в листинг 10.6 и ще видите следния резултат:
за d в „ls“.
do
if [ -f $d ] then echo
Свършен
Списък 10.7 съдържа прост for цикъл, който обикаля съдържанието на имената на
директориите (сродници). Кодовият блок if /else проверява дали директорията вече
съществува; ако е така, се показва съобщение; ако не, директорията се създава в
директорията names2 .
Стартирайте кода в листинг 10.7 и ще видите следния резултат:
за f в "ls"
направете if [ -d $f ] then
cd
$topdir/$f
else
echo "не може да намери remove.sh в $f" fi
cd $topdir fi
Свършен
КОМАНДАТА НА СЛУЧАЯ/ESAC
меню() {
опция:"
}
Machine Translated by Google
process_option() {
fi ;;
*) echo "Излизане от системата ... сбогом" изход ;;
esac
}
докато (вярно)
правя
меню
прочетете опцията
process_option
Свършен
Листинг 10.9 дефинира функцията menu() , която показва набор от опции, последвана
от функцията process_option() , която обработва входа, предоставен от потребителите.
Въведете опция: 1
Въведете опция: 2
Въведете опция:
х
Въведете опция: 4
Излизане от системата
КОМАНДАТА DD
dd if=/dev/sda1 of=sda1_partition.img
dd if=sda1_partition.img of=/dev/sda1
Предходната команда създава файл data.file , който е пълен с нули с размер 100 kb.
КОМАНДАТА КРОНТАБ
•
на почасова, дневна или седмична база
•
определен ден от месеца
•
определен месец или година
crontab
Трябва да сте или root потребител, или да използвате sudo, за да промените crontab (в
/usr/bin директория) със следната команда:
crontab -е
#!/bin/sh
zipfiles="`ls *zip`"
друго
Разделът съдържа набор от bash команди, които могат да бъдат полезни за различни задачи и
скриптове на shell. Можете да планирате изпълнение на команда в определено време чрез командата
at или чрез cron. Можете също така да планирате изпълнение на команда във фонов режим чрез
символа амперсанд („&“).
Използвайте или опцията -f , или пренасочване на въвеждане (<), когато имате нужда от
командата at , за да прочетете списък с команди от файл.
Командата nohup
nohup myscript.sh
След като влезете в отдалечена система, можете да изпълнявате различни команди между двете
системи. Например rcp е аналог на командата. Други команди включват rsync, ftp, ping и telnet. cp
Извършете онлайн търсене, за да научите подробностите за тези команди.
Превключвателят & изпълнява процес във фонов режим. Имайте предвид, че &
не понижава приоритета на текущия изпълняващ се процес. Тази опция е удобна за
извикване на две команди в една и съща обвивка:
fg %1
Можете да прекратите процес, чийто PID е 2345 с kill -3 2345 и kill -9 2345, които са
съответно сигнали QUIT и KILL . Сигналът QUIT обаче може да бъде „уловен” чрез
командата „trap”, докато сигналът KILL принуждава процеса да прекрати незабавно
(т.е. веднага щом операционната система може да изпълни тази команда). Освен това
сигналът KILL не може да бъде уловен чрез командата “trap” и не може да бъде
игнориран.
Machine Translated by Google
човек убива
The
пс командата показва информация за процесите на вашата машина.
Например, ако въведете следната команда от командния ред:
убийте -9 Chrome
23:21 до 1 ден, 12:59, 9 потребители, средни стойности на натоварване: 2,60 3,26 3,42
./cmdargs.sh
echo "резултат = $?"
cmdargs.sh
echo "резултат = $?"
$0 <filename>" exit 1
фи
изход 0
./cmdargs.sh
първи път:
резултат = 0 втори
път: Използване: ./
трети път:
Bash предоставя командата dmesg за показване на съобщения, свързани със системата. Примерен изход от командата
dmesg е тук:
Отворен файл /var/vm/sleepimage, размер 8589934592, дял база 0x0, maxio 400000 ssd 0 хибернация изображение
основно 1, второстепенно 0, размер на
блокове 512, избиратели 5 en1: BSSID променен на 68:7f:74:cb:05:f8
Machine Translated by Google
Както можете да видите, root потребителят е собственик на много от тези директории, така че
трябва да използвате sudo, за да видите съдържанието на тези директории.
Част от уместно наречения файл /var/log/zzz.log е тук:
ду -с -к .
#!/bin/sh
maxCount="10"
смяна на екрана()
{
echo "Уловен сигнал от командата за прихващане"
}
БРОЯ=0
докато [$COUNT -lt $maxCount]; направи
БРОЙ=$(($БРОЙ + 1))
сън 1
Свършен
Machine Translated by Google
Последната част от листинг 10.13 е for цикъл, който повтаря 10 пъти (т.е.
стойността, присвоена на променливата maxCount) и заспива за една секунда по време
на всяка итерация.
Списък 10.14 показва съдържанието на trap2.sh , което илюстрира как да
игнорирате сигнал в шел скрипт.
#!/bin/sh
"" ЗНАК
капан
ехо "control-c."
сън 10
АРИТМЕТИКА С КОМАНДИТЕ BC И DC
Bash shell не прави разлика между низове и числа (цели числа или реални числа).
Въпреки това, командата bc ви позволява да работите с числа, примери за които са
показани тук:
bc
bc 1.06
7
4,5 + 3,7
8.2
х=4
y = 7 echo
"$x * $y" |bc 28
#!/bin/bash #
Упражняване на командата 'date' echo "Броят дни от
началото на годината е 'date +%j'."
# Нуждае се от водещ '+' за извикване на форматиране. # %j дава ден от годината.
echo "Броят секунди, изминали от
01/01/1970 е 'дата +%s'." # %s дава брой секунди от началото на "BASH епохата", #+ но как е полезно това?
prefix=temp suffix=$
(date +%s) # Опцията "+%s" за 'date' е специфична за GNU. filename=$prefix.$suffix echo "Временно име на файл = $filename"
$ дата
Четвъртък, 20 май 23:09:04 IST 2010 г
$ дата +%s
1290047248
Опцията --date се използва за предоставяне на низ за дата като вход. Въпреки това можем да използваме
всякакви опции за форматиране на дата, за да отпечатаме изхода. Захранването на въведената дата от низ
може да се използва за намиране на деня от седмицата, като се има предвид датата. Ето един прост пример:
TOP=`pwd`
today=`date`
dayOfWeek=`echo $today |cut -d" " -f1` theMonth=`echo $today |
cut -d" " -f2` dateDir="${dayOfWeek}-${ theMonth}" newDir="$TOP/
$dateDir"
lpr myscript.sh
lpq
lp е готов и се печата
Ранг собственик Файлове за работа Обща сума
Размер
активен корен 155 /etc/passwd 1030
байтове
lprm 155
Machine Translated by Google
Предходната команда отменя отпечатването на задание номер 155. Въпреки това, само
потребителят, който е поискал файлът да бъде отпечатан (или root потребителят), може да
отмени отпечатването на файла.
DataFile="users.txt"
NAME="Джон Доу"
ADDRESS="1234 Appian Way, SF"
ТЕЛЕФОН="(555) 555-5555"
GPA="3,885"
DataFile="mylogfile.txt"
OK="добре"
ERROR="грешка"
sleeptime="2" loopcount=0
while (true) do
lastline='tail -1 $DataFile'
else
newline="`date` СИСТЕМНА ГРЕШКА"
fi
echo $newline >> $DataFile
elif [ "$badstatus" != "" ] then echo "Грешка в
Свършен
Machine Translated by Google
DataFile="mylogfile.txt"
OK="добре"
ERROR="грешка"
sleeptime="2" loopcount=0
Забележете, че две различни съобщения могат да бъдат добавени към лог файла: ако е добавено
съобщение за грешка, това съобщение ще бъде открито по време на следваща итерация на цикъла
while .
Въпреки това, ако okstatus е празен и променливата badstatus не е празна, тогава към лог файла
се добавя съобщение за грешка и командата break излиза от цикъла while . Примерно извикване на
листинг 10.17 е тук:
Грешка в регистрационния файл: петък, 27 септември, 21:28:53 PDT 2013 СИСТЕМНА ГРЕШКА
Този примерен код наистина е измислен, но можете да използвате същата (или подобна) логика,
в случай че трябва да анализирате съдържанието на регистрационен файл, за да проверите за
съобщения за грешка, след което можете да предоставите някакъв вид актуализация на състоянието.
Machine Translated by Google
22:30 до 28 дни, 14:18, 14 потребители, средни стойности на натоварване: 1,14 1,33 1,90
ПОТРЕБИТЕЛ TTY ОТ ВХОД@ ПРАЗЕН КАКВО
ocampesato конзола - ocampesato Четвъртък, 05 сутринта 28 дни -
- 10 vi shell-
s011 programming- Четвъртък, 05 сутринта
outline.txt
-
ocampesato s012 ocampesato Четвъртък05 сутринта 2 дни - баш
- Чет 05 сутринта 27:01 - баш
s000 ocampesato s002
- Четвъртък, 05 сутринта, 3:31 vi demo-list.txt
ocampesato s001 ocampesato
-
s004 events.txt Четвъртък05 сутринта 2 дни - баш
- Чет, 05 сутринта 33:52 vi todo-
-
ocampesato s007 Четвъртък05 сутринта 2 дни - баш
РАЗНИ КОМАНДИ
ИМЕ
ls -- списък на съдържанието на директорията
СИНОПСИС
ls [-ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1] [файл...]
ОПИСАНИЕ
За всеки операнд, който назовава файл от тип, различен от
указател,
ls показва своето име, както и всяко поискано свързано
информация-
полезен за определяне на времето или в процеси, работещи във фонов режим, проверяващи за
конкретно събитие от време на време (изпитване).
make -f myfile
ls -l | tee /tmp/файлове
ls -l | tee -a /tmp/файлове
през 2020 г. (или някоя друга година). Например, ако текущият месец и година са
февруари 2020 г., командата cal показва следния резултат:
февруари 2020 г
Су По Вт Ср Чет Пет Съб
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22
РЕЗЮМЕ
В този момент има още нещо да кажем: Поздравления! Завършили сте бърза, но
плътна книга и ако сте баш неофит, материалът вероятно ще ви занимава много
часове. Примерите в главите предоставят солидна основа, а приложението съдържа
допълнителни примери и случаи на употреба, за да илюстрира допълнително как
командите bash работят заедно. Комбинираният ефект показва, че вселената от
възможности е по-голяма от примерите в тази книга и в крайна сметка те ще
предизвикат идеи във вас. Късмет!
Machine Translated by Google
ИНДЕКС
А
AppendRow.sh, 91–92
Аритметични оператори, 71–
72 команда expr, 70–71 в
обвивки на POSIX, 70
масиви
array-function.sh, 97 array-loops1.sh,
97 в bash, 92–94 fruits-array1.sh ,
95 функция
items(), 97 names.txt и array-from-
file.sh, 96 команда awk
(Aho, Weinberger и Kernighan), 146 вградени променливи,
146 условна логика и контролни изрази, 148–151 броя на
срещанията на низ,
163–164 честота на преброяване на думи от набори
от данни, 170–171 изтриване на
случай на използване,
Bourne shell,
функция за заместване на 2 команди,
18 подкатегории, 2
д
Набори от данни
команда cd, 44
44
Дърво на директории, 42
на средата, 14–15
команда env, 13
Собственост на файла, 11
Files
31 създаване на текстови
файлове, 29–30
изтриване на файлове, 31–32
dirname команда, 39
малко, 35 преместване на
40–41 команди
chown и chgrp,
41 команди umask и ulimit, 41
Главна команда, 8
Скрити файлове, 11–12
аз
команда за присъединяване, 52
Linux, 2
Метасимволи, 24–25 и
класове знаци, 47–48 имена на
файлове и 48–49
Machine Translated by Google
od command, 56–57
Оператори
аритметични оператори, 71–72
команда expr, 70–71 в
обвивки на POSIX, 70
булеви оператори, 70, 75–76
оператори за тестване на
файлове, 70, 77–78 оператори за низове, 70, 75–76
команда за поставяне, 20
вмъкване на празен ред с, 21–22
Q
Цитати знаци, видове, 45–46
sourcing, 182
su команда, 248 &
switch, 234
sync и cal команда, 249 tee
команда, 248 top
команда, 236 trap
оператор, 239–240 uuencode
програма, 230–231 who
команда, 246–247 zip
файлове съдържат SVG документи, 201 –202
команда за сортиране, 53–
55 команда за разделяне, 53
Потоци и команди за пренасочване, 46–47
Стрингови оператори, 70, 75–76
Низове в shell скриптове, 82
T
tail команда, 8–9 команда
tee, 62 tr команда,
57–60
V
Променливи,
У
команда wc, 7
команда whatis, 15
команда whereis, 15 команда
which, 15 оператори
while, case/esac и if/elif/else/fi, 88–89 цикъл while, 86–88
27 конфигурация, 27