Linux: soubory - roura



1. Přesměrování výstupu

Kromě předchozích typů přesměrování > a >>, které už známe, existuje ještě několik dalších:

Pozn: ta dvojka je číslo datového proudu stderr.

příkaz 2> soubor
příkaz 2>> soubor
příkaz &> soubor

2. Přesměrování vstupu

Znak < přesměruje standardní vstup ze souboru:

příkaz < soubor

Tato konstrukce se používá zejména ve skriptech, kdy má nějaký příkaz postupně načítat data ze souboru:

while read i
do
  echo $i #vypisuje radky ze souboru data.txt
done < data.txt

Předchozí skript jde napsat i bez přesměrování vstupu:

for i in $(cat data.txt)
do
  echo $i #vypisuje radky ze souboru data.txt
done

☝ Příklady krásně demonstrují sílu terminálu a skriptů. Stejná činnost jde napsat různým způsobem.

3. Kombinace přesměrování

Příkaz du -s <adresar> vypíše celkovou velikost adresáře. Na ukázku vypíšeme adresář /etc. Nejprve na stdout a poté do souboru out1:

$ du -s /etc
$ du -s /etc > out1

V obou případech se nepřesměruje stderr. Ten je nutné přesměrovat samostatně:

$ du -s /etc 2> out2
$ du -s /etc > out1 2> out2

Pokud se stderr chceme prostě jen zabavit, pošleme do do speciálního souboru /dev/null. V něm nenávratně zmizí (soubor /dev/null se chová jako „černá díra“).

$ du -s /etc 2> /dev/null
$ du -s /etc > out1 2> /dev/null

4. Roura

V Unixových systémech je mnoho převážně jednoúčelových příkazů. Není to nedostatek, ale naopak přednost. Můžete si z nich poskládat komplexnější příkaz, který udělá přesně to, co požadujete. V tom spočívá pravá síla a "svoboda" Unixových systémů.

"Svoboda" v tomto kontextu znamená, že v okenních systémech jste omezeni pouze na možnosti nástrojů, které autoři systému vytvořili. V terminálu si je jednoduše seskládáte na míru sami.

Pomocí roury (pipe) se přesměruje výstup jednoho příkazu (stdout) na vstup druhého příkazu (stdin). Zapisuje se znakem | (svislá čára):

$ prikaz1 | prikaz2

A pokud je to potřeba, výstup druhého na vstup třetího atd. (dvě a více rour se nazývá „kolona“):

$ prikaz1 | prikaz2 | prikaz3

A pokud je potřeba, pak výstup posledního do souboru:

$ prikaz1 | prikaz2 | prikaz3 > soubor

A pokud by to stále nestačilo, můžete si napsat svůj skript nebo vlastní program v jazyce C. Záleží jen na vašich schopnostech.

5. tee

Nedostatkem přesměrování výstupu je skutečkost, že se odesílá buď na obrazovku nebo do souboru. Nikdy ne na oba výstupy najednou. Toto řeší příkaz tee. Obecná syntaxe je:

tee [-a] [soubor]

Příkaz tee čte stdin, posílá je na stdout a zároveň ho zapisuje do souboru. S přepínačem -a je přidává na konec.

Typické využití:

příkaz | tee [-a] soubor
příkaz 2> /dev/null | tee [-a] soubor

6. less

Příkaz less vypisuje obsah textového souboru včetně stránkování a hledání:

$ less /etc/php/7.0/apache2/php.ini

S přepínačem -N zobrazuje čísla řádků. Pro pohyb se používají běžné klávesy jako šipky nahoru a dolů, PgDown, PgUp. Klávesa q ukončí výpis (quit). Hledat řetězec v textu je možné zadáním / a hledaného řetězce (/vzor). Přechod na další výskyt se provede klávesou n, předchozí klávesou N.

Příkaz less tedy čistě technicky čte stdin a stránkovaně jej posílá na stdout. Toho lze využít a pomocí roury stránkovat jakýkoliv výstup libovolného příkazu:

$ ls -l /usr/bin | less
$ ls -l /usr/bin | less -N

7. grep

Příkaz grep čte stdin (nebo soubor) a vypisuje pouze ty řádky, které obsahují zadaný vzor.

$ grep vzor [soubor]

Bez souboru čte stdin (jako většina ostatních příkazů). Zkuste příkaz:

$ grep pa

a postupně vkládejte slova: „papousek“, „lipan obecny“, „slon indicky“, „salova kopana“, „zelena paprika“… Na stdout pošle grep pouze řádky obsahující vzor „pa“, ostatní odfilruje (nevypíše na stdout). Vkládání ukončíte Ctrl+D. Vyzkoušejte i pro jiný řetězec a vstup.

Příkazem wget si stáhněte soubor alice.txt
(zdroj: gist.github.com/phillipj/4944029/)

$ wget http://www.edumach.cz/files/alice.txt

Ze souboru alice.txt vypíšeme pouze řádky, obsahující slovo „rabbit“:

$ grep rabbit alice.txt

grep má mnoho přepínačů. Užitečné jsou zejména:

Víceslovný řetězec se uzavírá do uvozovek:

$ grep "rabbit hole" alice.txt

Tím možnosti grepu zdaleka nekončí. S využitím „žolíkových“ znaků (regulárních výrazů) a roury získáte velmi výkonný filtr.

7.1. Regulární výrazy

Regulární výraz (regular expression, zkráceně REGEX) je speciální řetězec znaků, který představuje určitý vzor (masku) pro hledání:

Základní regulární výrazy:

Vyzkoušejte je na souboru alice.txt.

Regulárních výrazů je mnohem víc: https://regularnivyrazy.info/.

7.2. Rourou do grepu

Pomocí roury umí příkaz grep filtrovat libovolný výstup (čte přece stdin):

$ ls /home | grep 16M

Pomocí více grepů se filtruje kaskádovitě:

$ grep Alice alice.txt | grep dancing
$ ls /home | grep 16M | grep -i ka

8. sort

Příkaz sort setřídí obsah souboru nebo spojí více souborů do jednoho setříděného souboru. Bez parametrů seřadí řádky souboru podle kódu ASCII: čísla, velká písmena, malá písmena.

Užitečné přepínače:

$ sort alice.txt
$ sort -u alice.txt
$ ls /home | grep 16M | sort -R

9. wc

Příkaz wc (word count) spočítá a vypíše počet řádků, slov a jednotlivých znaků souboru. Za slovo je považován řetězec znaků oddělený mezerou, tabulátorem nebo znakem nového řádku (CR, LF).

Není-li zadáno jméno souboru, čte ze standardního vstupu.

$ wc soubor
99 458 3114 soubor

Pomocí parametrů příkazu lze určit, které informace má vypisovat:

Například následující příkaz vypíše počet přihlášených uživatelů:

$ who | wc -l
5

10. tr

Velmi užitečný příkaz. Funguje jako filtr – čte proud bytů ze standardního vstupu a výsledek zapisuje na standardní výstup, aniž by měnil vstupní soubor. Bez roury se neobejdete:

tr "<hledat>" "<nahradit>"

Znaky vstupu, které se vyskytují v prvním řetězci budou nahrazeny odpovídajícími znaky druhého řetězce:

$ cat file | tr "a" "A"           # a za A
$ cat file | tr "iy" "IY"         # i a y za I a Y
$ cat file | tr "," "."           # čárka za tečku
$ cat file | tr "[a-z]" "[A-Z]"   # na velká písmena
$ cat file | tr "\t" " "          # tabulátory na mezery

Pro odstranění znaku slouží přepínač -d:

$ cat file | tr -d ","            # odstraní všechny čárky

Existují i zápisy typu [:upper:] (velká písmena), které zastoupí zápis [A-Z]. Hledejte va manuálové stránce příkazu tr. Příklad alternativního zápisu:

$ cat file | tr [a-z] [A-Z]
$ cat file | tr [:lower:] [:upper:]

11. sed

sed je neinteraktivní textový editor (stream editor). Používá se zejména pro provádění změn textu nebo pro manipulaci s rozsáhlými texty. Editor sed postupně čte řádky vstupního souboru, provádí zadané příkazy a výsledek zapisuje na standardní výstup.

Velmi často se používá pro nahrazování řetězců v souborech:

$ sed 's/vzor/novy-text/g' soubor

nahradí při výpisu textu všechny výskyty vzoru za novy-text.

Pro uchování změn je buď potřeba přesměrovat standardní výstup do souboru nebo využít přepínač -i, který čtený soubor přepíše.

$ sed 's/vzor/novy-text/g' soubor > soubor2
$ sed -i 's/vzor/novy-text/g' soubor

Možnosti využití sedu jsou mnohem větší:
www.howtogeek.com/666395/how-to-use-the-sed-command-on-linux/.

12. file

file soubor

Příkaz file zobrazí typ souboru, kódování a typ ukončení řádků, pokud není LF.

file1: ASCII text
file2: ASCII text, with CR line terminators
file3: ASCII text, with CRLF line terminators
file4: Little-endian UTF-16 Unicode text, with very long lines, with CRLF line terminators

Typy konců řádků operačních systémů:

LF     Linux/UNIX   ASCII kód 10       Line Feed
CR     macOS        ASCII kód 13       Carriage Return
CRLF   Windows      ASCII kód 13 + 10

13. ASCII tabulka

$ ascii -d

Příkaz zobrazí základní část ASCII tabulky (prvních 128 znaků).

    0 NUL    16 DLE    32      48 0    64 @    80 P    96 `   112 p
    1 SOH    17 DC1    33 !    49 1    65 A    81 Q    97 a   113 q
    2 STX    18 DC2    34 "    50 2    66 B    82 R    98 b   114 r
    3 ETX    19 DC3    35 #    51 3    67 C    83 S    99 c   115 s
    4 EOT    20 DC4    36 $    52 4    68 D    84 T   100 d   116 t
    5 ENQ    21 NAK    37 %    53 5    69 E    85 U   101 e   117 u
    6 ACK    22 SYN    38 &    54 6    70 F    86 V   102 f   118 v
    7 BEL    23 ETB    39 '    55 7    71 G    87 W   103 g   119 w
    8 BS     24 CAN    40 (    56 8    72 H    88 X   104 h   120 x
    9 HT     25 EM     41 )    57 9    73 I    89 Y   105 i   121 y
   10 LF     26 SUB    42 *    58 :    74 J    90 Z   106 j   122 z
   11 VT     27 ESC    43 +    59 ;    75 K    91 [   107 k   123 {
   12 FF     28 FS     44 ,    60 <    76 L    92 \   108 l   124 |
   13 CR     29 GS     45 -    61 =    77 M    93 ]   109 m   125 }
   14 SO     30 RS     46 .    62 >    78 N    94 ^   110 n   126 ~
   15 SI     31 US     47 /    63 ?    79 O    95 _   111 o   127 DEL

14. xxd

xxd vypíše obsah souboru v hexadecimálním nebo binárním tvaru (-b). Přepínač -u vypisuje písmena v hex výstupu velkými písmeny (ABCDEF).

$ xxd <soubor>
$ xxd -b <soubor>
$ echo "Panska" | xxd

Příklady:

$ xxd file.txt
00000000: 4a61 726f 2c20 6c65 746f 0a Jaro, leto.
$ xxd -u file.txt
00000000: 4A61 726F 2C20 6C65 746F 0A Jaro, leto.
$ xxd -b file.txt
00000000: 01001010 01100001 01110010 01101111 Jaro
00000004: 00101100 00100000 01101100 01100101 , le
00000008: 01110100 01101111 00001010          to.

15. iconv

iconv [soubor] [-f kodovani] [-t kodovani] [-o soubor]

Převede soubor z jednoho kódování (-f) do jiného (-t). Výstup posílá na stdout. S parametrem -o [soubor] jej uloží do souboru.

Seznam všech podporovaných kódování vypíše příkaz

$ iconv -l

V linuxu jej nejčastěji využijete pro převod do „čistého“ ASCII kódování (odstranění diakritiky). To vyžaduje dodatečný parametr //TRANSLIT:

$ iconv file -f UTF-8 -t ASCII//TRANSLIT -o file_plain

16. awk

Awk je také často používaný program pro práci s textem. Obecná syntaxe:

$ awk 'program' [soubor]

Program je série pravidel, která mohou obsahovat vzor, akci nebo obojí. Akce je uzavřena do { }. Když je ve vstupu nalezen vzor, vykoná se příslušná akce.

Příklad níže zobrazí jen druhý sloupec souboru:

$ awk '{print $2}' soubor

awk implicitně očekává sloupce oddělené mezerami. Jiný oddělovač se zapisuje za přepínač -F:

$ awk -F; '{print $1,$3}' data.csv

příkaz výše vypíše první a třetí sloupec souboru data.csv, kde oddělovač je znak ; (středník).

Příkaz awk toho umí výrazně víc:
www.howtogeek.com/562941/how-to-use-the-awk-command-on-linux/

17. 🖥️ Cvičení

Vytvořte adresář ~/roura1 a v něm soubor r1.txt. Do něj pište číslované odpovědi v podobě příkazů, které danou činnost vykonají. Využijte manuálové stránka příkazů.

  1. Vypište prvních 12 řádků souboru text.txt (příkaz head).
  2. Vypište poslední 2 řádky souboru /var/log/vysledky.log (příkaz tail).
  3. Zjistěte, zda mají soubory fileA na fileB stejný obsah (příkaz cmp).
  4. Vypište obsah pracovního adresáře (široký výpis, včetně skrytých souborů), použijte stránkovací příkaz less.
  5. Vypište obsah souboru /etc/passwd, a to setříděně (reverzní, tzn. opačné pořadí).
  6. Vypište obsah svého home adresáře včetně skrytých souborů. Výsledek přesměrujte do souboru seznam.txt.
  7. Zjistěte počet řádků souboru /etc/fstab.
  8. Příkaz tr "eth0" "eth1" zamění všechny výskyty prvního řetězce druhým. Napište příkaz, který změny provede a uloží je do souboru eth.txt.