GNU/Linux >> Znalost Linux >  >> Linux

Procházení obsahu souboru v Bash

cat peptides.txt | while read line 
do
   # do something with $line here
done

a varianta s jednou vložkou:

cat peptides.txt | while read line; do something_with_$line_here; done

Tyto možnosti vynechají poslední řádek souboru, pokud tam není žádný konec řádku.

Tomu se můžete vyhnout následujícím způsobem:

cat peptides.txt | while read line || [[ -n $line ]];
do
   # do something with $line here
done

Možnost 1a: Zatímco smyčka:Po jednom řádku:Přesměrování vstupu

#!/bin/bash
filename='peptides.txt'
echo Start
while read p; do 
    echo "$p"
done < "$filename"

Možnost 1b: Zatímco smyčka:Po jednom řádku:
Otevřete soubor, čtěte z deskriptoru souboru (v tomto případě deskriptoru souboru #4).

#!/bin/bash
filename='peptides.txt'
exec 4<"$filename"
echo Start
while read -u4 p ; do
    echo "$p"
done

To není o nic lepší než jiné odpovědi, ale je to další způsob, jak provést práci v souboru bez mezer (viz komentáře). Zjistil jsem, že často potřebuji jednoduché řádky k procházení seznamů v textových souborech bez dalšího kroku používání samostatných souborů skriptů.

for word in $(cat peptides.txt); do echo $word; done

Tento formát mi umožňuje umístit vše na jeden příkazový řádek. Změňte část "echo $word" na cokoli chcete a můžete zadat více příkazů oddělených středníky. Následující příklad používá obsah souboru jako argumenty do dvou dalších skriptů, které jste možná napsali.

for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done

Nebo pokud to máte v úmyslu použít jako stream editor (naučte se sed), můžete výstup uložit do jiného souboru následovně.

for word in $(cat peptides.txt); do cmd_a.sh $word; cmd_b.py $word; done > outfile.txt

Použil jsem je, jak je napsáno výše, protože jsem použil textové soubory, kde jsem je vytvořil s jedním slovem na řádek. (Viz komentáře) Pokud máte mezery, které nechcete rozdělovat slova/řádky, bude to trochu ošklivější, ale stejný příkaz stále funguje následovně:

OLDIFS=$IFS; IFS=$'\n'; for line in $(cat peptides.txt); do cmd_a.sh $line; cmd_b.py $line; done > outfile.txt; IFS=$OLDIFS

To pouze řekne shellu, aby se rozdělil pouze na nové řádky, nikoli na mezery, a pak vrátí prostředí zpět do toho, co bylo dříve. V tuto chvíli však možná budete chtít zvážit vložení všeho do skriptu shellu spíše než vtěsnat vše do jednoho řádku.

Hodně štěstí!


Jeden způsob, jak to udělat, je:

while read p; do
  echo "$p"
done <peptides.txt

Jak bylo zdůrazněno v komentářích, má to vedlejší účinky ořezávání úvodních mezer, interpretace sekvencí zpětného lomítka a přeskočení posledního řádku, pokud v něm chybí ukončovací řádek. Pokud máte tyto obavy, můžete:

while IFS="" read -r p || [ -n "$p" ]
do
  printf '%s\n' "$p"
done < peptides.txt

Výjimečně, pokud tělo smyčky může číst ze standardního vstupu, můžete soubor otevřít pomocí jiného deskriptoru souboru:

while read -u 10 p; do
  ...
done 10<peptides.txt

Zde je 10 pouze libovolné číslo (odlišné od 0, 1, 2).


Linux
  1. Procházení souborů s mezerami v názvech?

  2. Proč skript Bash nerozpozná aliasy?

  3. Přesměrování obsahu souboru na příkaz „echo“?

  1. The Bash ‘?

  2. Hromadné přejmenování souboru Bash pomocí čítače?

  3. Bash skript k odstranění nejstaršího souboru ze složky?

  1. Uložit veškerý výstup z terminálu do souboru?

  2. Jak poznám název souboru skriptu ve skriptu Bash?

  3. Procházení prvků proměnné cesty v Bash