GNU/Linux >> Znalost Linux >  >> Linux

Rozdělit výstup příkazu podle sloupců pomocí Bash?

Jedním snadným způsobem je přidat heslo tr pro vytlačení všech opakovaných oddělovačů polí:

$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4

Vezměte prosím na vědomí, že tr -s ' ' možnost neodstraní žádné jednotlivé mezery na začátku. Pokud je sloupec zarovnán vpravo (jako u ps pid)...

$ ps h -o pid,user -C ssh,sshd | tr -s " "
 1543 root
19645 root
19731 root

Pokud se jedná o první sloupec, vyjmutí bude mít za následek prázdný řádek pro některá z těchto polí:

$ <previous command> | cut -d ' ' -f1

19645
19731

Samozřejmě, pokud před ní není mezera

$ <command> | sed -e "s/.*/ &/" | tr -s " "

Nyní, pro tento konkrétní případ čísel pid (nikoli jmen), existuje funkce nazvaná pgrep :

$ pgrep ssh


Funkce shellu

Obecně je však stále možné používat funkce shellu stručně, protože na read je pěkná věc příkaz:

$ <command> | while read a b; do echo $a; done

První parametr ke čtení, a , vybere první sloupec, a pokud je jich více, vše ostatní bude vložen do b . V důsledku toho nikdy nepotřebujete více proměnných, než je číslo vašeho sloupce +1 .

Takže

while read a b c d; do echo $c; done

pak vypíše 3. sloupec. Jak je uvedeno v mém komentáři...

Čtení pomocí kanálu bude provedeno v prostředí, které nepředává proměnné volajícímu skriptu.

out=$(ps whatever | { read a b c d; echo $c; })

arr=($(ps whatever | { read a b c d; echo $c $b; }))
echo ${arr[1]}     # will output 'b'`


Řešení pole

Takže pak skončíme s odpovědí @frayser, která spočívá v použití proměnné shellu IFS, která má výchozí hodnotu mezeru, k rozdělení řetězce do pole. Funguje to ale pouze v Bash. Dash a Ash to nepodporují. Měl jsem opravdu těžký čas rozdělit řetězec na komponenty ve věci Busybox. Je snadné získat jednu komponentu (např. pomocí awk) a poté to zopakovat pro každý parametr, který potřebujete. Ale pak skončíte tím, že opakovaně voláte awk na stejné lince nebo opakovaně používáte čtený blok s echem na stejné lince. Což není efektivní ani hezké. Takže skončíte rozdělením pomocí ${name%% *} a tak dále. Toužíte po některých dovednostech Pythonu, protože skriptování v shellu už není moc zábavné, pokud polovina nebo více funkcí, na které jste zvyklí, jsou pryč. Ale dá se předpokládat, že ani python by se na takový systém nenainstaloval a nebylo;-).


Myslím, že nejjednodušší je použít awk . Příklad:

$ echo "11383 pts/1    00:00:00 bash" | awk '{ print $4; }'
bash

Linux
  1. Použití příkazu Linux Basename ve skriptech Bash

  2. Jak rozdělit iso nebo soubor pomocí příkazu „split“ v Linuxu

  3. Automaticky zachytit výstup posledního příkazu do proměnné pomocí Bash?

  1. Použití Linux Sleep Command ve skriptech Bash

  2. příkaz pro export bash

  3. Přesměrovat výstup příkazu time v unixu do proměnné v bash?

  1. Použití výstupu předchozích příkazů v bash

  2. Přesměrování výstupu příkazu do proměnné v bash se nezdaří

  3. Přesměrovat veškerý výstup do souboru pomocí Bash na Linuxu?