Omezení počtu znaků při vyhledávání pomocí grep

V jednom z předchozích příspěvků jsem se věnoval základnímu vyhledávání pomocí příkazu grep. Tento příkaz hledá zadaný vzor a pokud jej najde, výsledek vypíše na standardní výstup. Problém může nastat v případě, že nalezený řádek je velmi dlouhý (např. xml soubor na jediném řádku v logu). To se dá vyřešit kombinací příkazu grep s příkazem cut.

grep pattern nazev_souboru | cut -c -80
grep pattern nazev_souboru | cut -c 1-80

Tyto dvě posloupnosti příkazů dávají stejný výsledek. Vrátí první až osmdesátý znak z každé řádky nalezené grepem.

grep pattern nazev_souboru | cut -c 40-100

Vrátí čtyřicátý až stý znak z každého řádku nalezeného grepem.


Zdroj: stackoverflow.com/…characters-one-line

Spring: metody init a destroy

Spring za nás vytváří instance tříd a dává nám je k dispozici na požádání. Tím požádáním může být například volání metody getBean(). To, jak se má instance vytvořit, si Spring přečte v konfiguračním souboru. Spring tedy potřebuje konfigurační soubor (beans.xml) k tomu, aby věděl, jaké a jak má instance (beany) vytvářet. Spring nejen instance (beany) vytváří ale řídí celý jejich životní cyklus od vytvoření až po zničení. Spring umožňuje nadefinovat metody, které se mají zavolat při inicializaci instance nebo při jejím ukončení. Jak bylo uvedeno výše, Spring vytváří instance na základě konfigurace. To zda a jaké metody se v určitých fázích životního cyklu instance mají zavolat, je tedy třeba uvést v konfiguraci dané beany.

Struktura projektu

│   pom.xml
│
└───src
    ├───main
    │   └───java
    │       └───cz
    │           └───vitfo
    │               └───spring
    │                       Main.java
    │                       MyClass.java
    │
    └───resources
            beans.xml

MyClass.java

public class MyClass {
	
	private String message;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
	
	public void myInit() {
		System.out.println("Zavolána metoda init().");
	}
	
	public void myDestroy() {
		System.out.println("Zavolána metoda destroy().");
	}
}

beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean 	class="cz.vitfo.spring.MyClass" 
   			init-method="myInit" 
   			destroy-method="myDestroy">
   			<property name="message" value="Hello"></property>
   </bean>

</beans>

Main.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
    	ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    	
    	MyClass mc = context.getBean(MyClass.class);
    	
    	System.out.println(mc.getMessage());
    	
    	// Context funguje jako úložiště všech Springem vytvořených bean (instancí).
    	((ConfigurableApplicationContext) context).close();
    }
}

Výsledek

Zavolána metoda init().
Hello
Zavolána metoda destroy().

Popis
V konfigurační souboru jsme pro beanu MyClass definovali metody, které se mají zavolat při inicializaci (init-method=“myInit“) a před zničením (destroy-method=“myDestroy“). Tyto metody jsou ve třídě MyClass a pouze při svém zavolání vypíší text, jak je vidět v konzoli.

Proč nepoužívat double pro přesné výpočty

Čísla s desetinnou čárkou jsou v počítači reprezentována podle standardu IEEE 754. Tato reprezentace ale není přesná což může vést k následujícím situacím.

double x = 0.5;
double y = 0.4;
double z = x - y;

System.out.println("Hodnota z: \t" + z);

Výsledek

Hodnota z: 0.09999999999999998

Další příklad

double mixer = 1099.00;
double mixerPoSleve = mixer * 0.9;
double trouba = 5999.00;
double troubaPoSleve = trouba * 0.9;
double celkovaCena = troubaPoSleve + mixerPoSleve;

System.out.println("mixér po slevě: \t" + mixerPoSleve);
System.out.println("trouba po slevě: \t" + troubaPoSleve);
System.out.println("celková cena: \t\t" + celkovaCena);

Výsledek

mixér po slevě: 989.1
trouba po slevě: 5399.1
celková cena: 6388.200000000001

Řešením je použít datový typ BigDecimal. Zde je s použitím BigDecimal upraven první příklad.

BigDecimal x = new BigDecimal("0.5");
BigDecimal y = new BigDecimal("0.4");
BigDecimal z = x.subtract(y);

System.out.println("Hodnota z: \t" + z);

Výsledek

Hodnota z: 0.1

Čas v různých časových zónách v Javě 8

Pro určení časového pásma v Javě 8 slouží ZoneId. K jeho vytvoření se používá řetězec ve stylu kontinent/město. Seznam časových zón naleznete například na wiki.

ZoneId pragueZI = ZoneId.of("Europe/Prague");
ZoneId newYorkZI = ZoneId.of("America/New_York");
ZoneId vladivostokZI = ZoneId.of("Asia/Vladivostok");
ZoneId hawaiiZI = ZoneId.of("US/Hawaii");

System.out.println(pragueZI);
System.out.println(newYorkZI);
System.out.println(vladivostokZI);
System.out.println(hawaiiZI);

Výsledek

Europe/Prague
America/New_York
Asia/Vladivostok
US/Hawaii

Pro uchování/vytvoření času, který obsahuje i údaj o časové zóně slouží ZonedDateTime

ZonedDateTime pragueCurrent = ZonedDateTime.now(pragueZI);
ZonedDateTime newYorkCurrent = ZonedDateTime.now(newYorkZI);
ZonedDateTime vladivostokCurrent = ZonedDateTime.now(vladivostokZI);
ZonedDateTime hawaiiCurrent = ZonedDateTime.now(hawaiiZI);

System.out.println(pragueCurrent);
System.out.println(newYorkCurrent);
System.out.println(vladivostokCurrent);
System.out.println(hawaiiCurrent);

Výsledek

2016-09-21T16:35:32.602+02:00[Europe/Prague]
2016-09-21T10:35:32.609-04:00[America/New_York]
2016-09-22T00:35:32.609+10:00[Asia/Vladivostok]
2016-09-21T04:35:32.609-10:00[US/Hawaii]

Vyhledávání ve všech souborech pomocí grep

Pro vyhledávání v souborech se používá program grep což je program příkazové řádky dostupný na UNIX systémech.

grep Ahoj pokus2
Vyhledá slovo ‚Ahoj‘ v souboru pokus2.

grep Ahoj *
Vyhledá slovo ‚Ahoj‘ ve všech souborech v adresáři.

grep -r Ahoj *
Vyhledá slovo ‚Ahoj‘ ve všech souborech v adresáři a podadresářích.

grep -rl Ahoj *
Prohledá všechny soubory v aktuálním adresáři a podadresářích a vypšíše jména souborů, které obsahují slovo ‚Ahoj‘.

Výjimka java.time.DateTimeException: Invalid ID for ZoneOffset, invalid format

V Java 8 DateTime API existuje třída pro uchovávání data včetně časové zóny ZonedDateTime. Údaj o časové zóně může být reprezentován třídami ZoneId a ZoneOffset, kdy ZoneId uchovává časovou zónu a ZoneOffset posun oproti Greenwich času. Pokud tedy máme ZonedDateTime 2016-09-07T08:22:40.492+02:00[Europe/Prague] pak Europe/Prague představuje ZoneId a +02:00 ZoneOffset. ZoneOffset dědí ze ZoneId. Obě tyto třídy poskytují statickou metodu of(String zoneId), která na typu textového parametru vrací buď instanci ZoneId nebo ZoneOffset.

ZoneId zi1 = ZoneId.of("+3");
Vrátí ZoneOffset a protože ZoneOffset dědí ze ZoneId, je možné do datového typu ZoneId přiřadit ZoneOffset.

ZoneOffset zo1 = ZoneOffset.of("+3");
Vrátí ZoneOffset.

ZoneId zi2 = ZoneId.of("Asia/Vladivostok");
Vrátí ZoneId.

ZoneOffset zo2 = ZoneOffset.of("Asia/Vladivostok");
Vyhodí výjimku java.time.DateTimeException: Invalid ID for ZoneOffset, invalid format – do ZoneOffset se snažíme přiřadit ZoneId.

Directory listing a google

Povolený directory listing na serveru znamená, že je možné zobrazit soubory a složky na serveru. Pokud v daném souboru na serveru není startovní soubor (nejčastěji index.html), po přístupu na url se objeví html stránka se seznamem složek a souborů.

google_hacking_directory_listingPNG

Tato html stránka obvykle v obsahuje titulek „Index of“.

<html>
 <head>
  <title>Index of /~...</title>
 </head>
 <body>
<h1>Index of / ...

Pro vyhledání takovýchto webů lze použít google a jeho klíčové slovo intitle. Dotaz pro vyhledání takovýchto stránek by tedy mohl vypadat následovně intitle:"Index of".

Velikost poštovní schránky v Outlooku

Grafický pohled na zůstatek volného místa lze zjistit v Soubor -> Informace -> Vyčištění poštovní chránky

outlook_velikost_postovni_schranky

Pokud potřebujete přesný přehled včetně velikosti, které zabírají jednotlivé složky, Soubor -> Informace -> Vyčistění poštovní schránky (Nástroje pro vyčistění) -> Vyčištění poštovní schránky -> Zobrazit velikost schránky

outlook_velikost_postovni_schranky_02

Přejmenování sloupce v PostgreSQL

Přejmenování sloupce je velmi podobné vytvoření nového sloupce, které bylo popsáno v tomto příspěvku. Opět se používá příkaz ALTER TABLE jen místo ADD je RENAME. Syntaxe příkazu je následující.

ALTER TABLE nazev_tabulky RENAME COLUMN puvodni_nazev_sloupce TO novy_nazev_sloupce

Nejdříve si vytvoříme tabulku s daty a následně pak přejmenujeme její sloupce.

drop table if exists pokus;
create table pokus (
	id serial not null,
	name varchar(100) not null,

	primary key (id)
);

insert into pokus (name) values ('jnovak'), ('vlasak'), ('kvetinka');

Takto se provede přejmenování sloupců.

alter table pokus rename column id to id_pokus;
alter table pokus rename column name to username;