for loop, seq, touch etc.

Fórumok

Sziasztok,

Azt szeretném kérdezni, hogy meg lehet -e oldani ezt a 2 parancsot 1 ben?

for a in `seq 0 9`; do >0$a.txt; done
for b in `seq 10 30`; do >$b.txt; done

Azt szeretném, hogy a fájlnevek 01, 02 ... 09, 10, 11 stb néven jöjjenek létre.

Köszi

--Zoli

Hozzászólások

Ha a seq a kiszemelt eszközöd, akkor vess egy pillantást a -w kapcsolójára!

Ez is jó szerintem:

seq -f "track%02g" 1 20

Találtam egy jó kis tutorial videót a seq hez - abban voltak ilyesmik.
A seq manjából erre magamtól nem jöttem volna rá - sejtettem, hogy ilyet is lehet, csak azt nem írják a man seqban, hogy idézőjelek közé kellene tenni...

Meg ilyen kis nyalánkságok teszik érdekessé a seq kel való ismerkedést pl: seq -sw: 20 =/ seq -ws: 20

A 2. esetben az s 'separator' hez kapcsolódik a : jel, ezért úgy működik ahogy szerettem volna.

Találtam egy oldalt, ami nagyon tetszik: http://www.unixcl.com/

-- Zoli

Nem kell idézőjelek közé tenni. Az idézőjelek a shellnek szólnak, a seq semmit sem lát belőlük. Az más kérdés, hogy ha nem rakod idézőjelbe a stringet, akkor a shellnek szóló speciális karaktereket a shell értelmezi, és nem az történik, amit szeretnél. De erről a seq mit sem tud. Példa:

grep -v '^#' /etc/fstab | sed -r 's/ +/ /g' | cut -d' ' -f3


grep -v '^#' /etc/fstab | sed -r 's/ +/ /g' | cut -d\  -f3

Viszont hibás:

grep -v '^#' /etc/fstab | sed -r 's/ +/ /g' | cut -d   -f3
cut: the delimiter must be a single character
Try 'cut --help' for more information.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Bocsánat, már meg is fejtettem, -w kapcsoló!

Az a baj, hogy mindig egyszerűbb megkérdezni, mint utánanézni...
Azt hittem bonyolultabb ez.

-- Zoli

(Látom, hogy megvan.) Csak hogy egy nem teljesen triviális másfajta verziót is mutassak. Sajnálatos módon bash nem jó hozzá, valamiért ez csak ksh-ban működik (a bash látszólag nem ismeri a balra- és jobbra igazított változókat):

typeset -iZ2 j; j=1; while [ $j -lt 31 ] ; do touch $j.txt ; j=j+1 ; done

(Nyilván még jobb lenne, ha nem hívnánk mindegyikre touch-ot, hanem először legeneráljuk a fájlneveket, aztán pl egy $( .. ) formában odaadjuk ezt a touchnak.)

touch {00..30}.txt

BASH_VERSION=4.2.37(1)-release

~~~~~~~~
Linux 3.2.0-0.bpo.4-486
Debian 6.0.7

Ez is nagyon tetszik, fel is írtam, köszi az ötletet!

Mi a különbség a kettő között?

1. for i in `seq -w 10`; do >${i}.txt; done
2. touch {01..10}.txt

A touch megváltoztatja az időbélyeget - ennyit tudok, de ha for ciklussal hozom létre ezt a 10 fájlt, akkor lesz valami különbség a végeredmény tekintetében?
Megnéztem ls -l parancsal mindkét parancs kimenetét, de nekem úgy tűnik, hogy ugyanaz a végeredmény.

-- Zoli

Akkor van különbség, hogyha a file már létezett és volt benne valami, figyeld a módosítási időt és a file méretet:

$ ls -l bla
-rw-rw-r-- 1 sz sz 1048576 Apr 13 01:57 bla
$ touch bla
$ ls -l bla
-rw-rw-r-- 1 sz sz 1048576 Aug 31 09:45 bla
$ >bla
$ ls -l bla
-rw-rw-r-- 1 sz sz 0 Aug 31 09:46 bla

Attól függ, hogy mit értesz végeredmény alatt.

Ha konkrétan a 10 fájl létrehozására (vagyis egyik fájl sem létezik még) fókuszálunk, akkor hatásábn a kettő egyenértékű.
Viszont annak köszönhetően, hogy MÁSHOGY teszik, amit tesznek, más rendszeren, szélesebb intervallumot megadva a touch végeredménye lehet az, hogy nem fut le, vagyis nincs végeredmény.

Nézzük meg, hogy valójában mi fut le:


$ set -x
$ touch {01..10}.txt
+ touch 01.txt 02.txt 03.txt 04.txt 05.txt 06.txt 07.txt 08.txt 09.txt 10.txt

Vagyis a shell legyártja nekünk a röviden megfogalmazott parancsból az annak a megfelelő szó szerinti parancsot a 10 argumentummal, és azt futtatja.
Az argumentumok száma (a parancs hossza) nem növelhető minden határon túl:


getconf -a | grep ^ARG_MAX
ARG_MAX                            2097152

Ezen rendszeren, ha 2M-nál hosszabbra nőne, kapnék egy "arg list too long" üzenetet.
A korlát oprendszerenkén, kernelenként, sőt (ahol módosítható) futásonként változhat.

Tessék:

echo "$PS1"
\[\033[01;33m\]$? $(if [[ $? == 0 ]]; then echo "\[\033[01;32m\];)"; else echo "\[\033[01;31m\];("; fi) \[\033[1;32m\]\u@\h\[\033[01;34m\] \w $\[\033[00m\]

echo $PROMPT_COMMAND
printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"

Egyébként át fogom szerkeszteni a PS1 et ez alapján:

http://stackoverflow.com/questions/103857/what-is-your-favorite-bash-pr…

mivel ez így, ahogy most van olvashatatlan számomra.

-- Zoli

az a két jel egy 0x01 és egy 0x02 karaktert jelenít meg, de nem tudom, mi oka van rá, hogy kiírja. pontosan a \[ és a \] jelek helyén írja ki, amik arra valók, hogy a köztük lévõ karaktereket (ansi escape sequence) ne számolja hozzá a prompt hosszához, így a parancssor szerkesztése közben pontosan tudja, hol az eleje.

~~~~~~~~
Linux 3.2.0-0.bpo.4-486
Debian 6.0.7

A fenti magyarázattal együtt azt javaslom, ezen ne akadj fenn, vagyis ne ezen akadj fenn. Sikerült belefutnod, egy furcsa konstellációba a finomhangolt promptod folytán. Javaslom, hogy amikor a parancssorodat debuggolod, állíts konzervatívabb promptot, hogy ne takarja a fa az erdőt.

(DELETE által önlektorálva)

Asszem, pedzem. A bash a PS1-ben minden \[ és \] szekvenciát lecserél 0x01 (STX, start of text) illetve 0x02 (ETX, end of text) karakterre. Ezeket amikor saját maga formázza a promptot, szépen lenyeli, de itt továbbadja az egész szekvenciát az echonak (már az ANSI szekvenciákat feloldva), ami viszont ezért kénytelen azt kiírni.
A látható promptban egyiknek sincs nyoma (nincs vezérlő funkció), de ha a terminál tud UTF-8-at, a set -x belső formázása után a kimenet árulkodik a kódolástól idegen, funkciótlan karakterekről. UTF-8 nélkül az egésznek nyoma sincs.

Persze kérdés, mit nem értettél. A shell a globbingot, különféle helyettesítéseket kifejti egy bufferbe, majd átadja a parancsnak. A parancs nem tudja, hogy az argumentumok hogyan álltak elő: begépelték őket, vagy egy rafinált kifejezés állította elő.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Köszi.
Átírtam a 2 est 3 masra teszt céljából. Nagyon tetszik.
Hol lehetne utánanézni, hogy a g mit jelent stb. Gondolom a g mellett még léteznek más paraméterek is. Ez kicsit hasonlít a printf formázására, amit a K&R könyvben az elején írnak, de nem teljesen úg yműködik szerintem.

-- Zoli

Ezek azért nem túl jó doksik szerintem, legalábbis ezekből én még nem lettem okosabb:-( a -w egyértelmű, de ezek:

‘%a’, ‘%e’, ‘%f’, ‘%g’, ‘%A’, ‘%E’, ‘%F’, ‘%G’

Nem túl beszédes az ezekről írtak. Gondolom ez annak egyértelmű, aki tud c ben programozni. gyakorlatiasabb példákból mindig hamarabb sikerült valamire rájönnöm, mint ilyen doksik, meg man oldalak olvasgatásából.

-- Zoli