Sziasztok. Abba a problémába futottam bele, hogy egy fileból ki kellene törölnöm minden olyan sort, ami egy megadott stringet tartalmaz. A probléma az, hogy a megadott string valójában valamilyen útvonal, vagyis tartalmaz / jelet.
Azt olvastam; hogy ilyenkor a sed parancsot át kell alakítani, hogy az elválasztójel | legyen. pl:
sed -i "s|$f|valami|g" file
Viszont ez a megoldás nem működik, ha sor törléséről van szó:
sed -i "|$f|d" file
Ekkor expression errort és unknown | -t ír ki.
Most ideiglenesen úgy oldottam meg, hogy elöszőr kicserélem egy olyan karakterláncra, ami sose fordulna elő, és utána azt a karakterláncot törlöm, tehát:
sed -i "s|$f|valami85473wert|g" file
sed -i '/valami85473wert/d' file
Csak azért ez nem egy túl elegáns megoldás, még ha így logikus és műküdik is. Van arra megoldás, hogy a sed-nél ha sort törlök, akkor a változóban szereplő / jel ne zavarja meg?
- 504 megtekintés
Hozzászólások
Bashban lehet ezzel próbálkozni:
sed "s/${f//\//\\\/}/valami/g" ...
(escapeled a $f-et)
- A hozzászóláshoz be kell jelentkezni
ha s/-t használok, mert cserélni kell, akkor nincsen gond, működik a | használata. Itt pont az lenne a lényeg, hogy a sed-el sort akarok törölni, aminek esetében változót használok, ami mindig tartalmaz / jelet, és azt hogyan lehet megoldani.
- A hozzászóláshoz be kell jelentkezni
Ugyanígy (a fenti sor nem a sed elválasztót cseréli, hanem escapeli a / jelet, azaz a sed nem "érti félre").
- A hozzászóláshoz be kell jelentkezni
A sed-nel a /.../ a range, amin az utana megadott parancsot vegrehajtja, mig az 's' a replace parancs, aminel parameterezheto az elvalaszto karakter. sed "\A${f}A d" ?
- A hozzászóláshoz be kell jelentkezni
sed "\A${f}A d" file nem működik.
Amúgy értem, hogy a / közötti a range alapesetben, de megadott sorok törléséhez is pont ugyanígy kell használni:
sed "/valami/d" file -> ebben az esetben minden olyan sort töröl, amiben szerepel a valami szó.
- A hozzászóláshoz be kell jelentkezni
Szerintem két hiba van az általad megadott fomában.
Az egyik (szintaktikai), hogy a szóköz karakter miatt nem annyira értelmes.
A másik (elvi), hogy a shell-ben idézőjelen belül a \-t is speciálisan értelmezi a shell (de csak bizonyos karakterek előtt!), szóval a te példád épp jó, de ha valaki másik karaktert ír a \ után, ajkor belefuthat nagy szopásba. Én e miatt leggyakrabban a , (vessző) karaktert használom, azaz a /minta/ helyett ezt írom: \,minta, .
Az általad írt megoldás helyes formája így néz ki:
sed "\A${f}Ad"
- A hozzászóláshoz be kell jelentkezni
Köszi, ez így már jól működik nekem:
sed -i "\A${f}Ad" file
- A hozzászóláshoz be kell jelentkezni
https://man.archlinux.org/man/core/sed/sed.1.en
- \cregexpc
- Match lines matching the regular expression regexp. The c may be any character
Vagyis:
sed -i "\\,$f,d" file
De ehhez is kell tudnod mondani legalább 1 karaktert ami nem lehet a regexben, amit separátorként használsz.
- A hozzászóláshoz be kell jelentkezni
Köszi, így már értem. A Vessző helyett, akkor inkább : -ot raktam, mert az biztos nem lesz az elérési útban. Mégegyszer köszönöm a segítséget.
- A hozzászóláshoz be kell jelentkezni
A sed tudtommal szöveges fájlok soronkénti manipulálását végzi. Amennyiben probléma az is hogy kitörölje a sort és ne csak egy newline-t hagyjon ott akkor más tool pl awk felé nézelődnék. Belefutottam hasonlóba, bár sed a problémák 90%-ban egyszerűbb volt (mivel awk-t mai napig nem tanultam meg rendesen), ellenben awk az igazi svájci bicska.
- A hozzászóláshoz be kell jelentkezni
Én is AWK felé mentem volna első olvasásra a sed helyett. Esetleg egy megfelelően paraméterezett grep parancs is meg tudja talán oldani ezt.
Mivel az egész sort kellene törölni, ezért a sed sztem. nem feltétlen jó irány.
A tuti megoldás az awk lesz sztem.
- A hozzászóláshoz be kell jelentkezni
Az kb így néz ki:
awk -i inplace -v pat="$f" '$0 !~ pat { print $0 }' file
Az az előnye mindenképpen megvan a seddel szemben, hogy nem kell kiválasztani egy karaktert ami nem szerepel a patternben.
- A hozzászóláshoz be kell jelentkezni
A { print $0 } feleslegss, ugyanis az az alapértelmezett akció.
Jav: amúgy ez a -i inplace hol létezik? A One-True-AWK. a mawk, a goawk és nálam a gawk manuálja sem említi.
- A hozzászóláshoz be kell jelentkezni
GNU
- A hozzászóláshoz be kell jelentkezni
$ gawk --version
GNU Awk 5.3.0, API 4.0
Ez nem ismeri. (FreeBSD alatt)
- A hozzászóláshoz be kell jelentkezni
Ah valóban. Ez a gawk-ban létezik csak.
Akkor viszont kénytelen vagy vagy gawk-t használni vagy a sima awkkal az inplace helyett a moreutils sponge parancsát használni vagy egy temp fájlba írni az eredményt majd azzal felülírni az eredeti fájlt.
- A hozzászóláshoz be kell jelentkezni
Pont azt magyarázom, hogy a FreeBSD-hez bináris csomagból feltett gawk SEM ismeri.
Jav.
OK. A man-ban és a help-ben sem említi, de felismeri és működik is. Kösz, akkor tanultam egy fasza undoc featúrát.
- A hozzászóláshoz be kell jelentkezni
https://www.gnu.org/software/gawk/manual/html_node/Extension-Sample-Inp…
Ennyire undoc. Nem feature, a -i behuz egy include file-t, ez az inplace nevu meg pont ezt csinalja.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
Ismétlem: nincs benne a man gawk-ban és gawk --help -re sem említi. Persze tudom, a man gyengéknek való, ráadásul vérbeli GNU szoftver az info-ban dokumentálja a működést. (Most ellenőriztem, abban benne van, igaz nekem nincs telepítve info olvasó.)
- A hozzászóláshoz be kell jelentkezni
Ugy vettem ki, hogy ez nem maga a gawk, hanem annak egy library-je. Azert kell -i-vel betolteni.
Ugyanaz, mint ha a python scriptedbe beimportalnal mondjuk egy numpy-t, annak a doksijat sem a man python-ban fogod megtalalni, hanem a neki megfelelo helyen.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
Esetleg;
fgrep -v -- "$f" file
- A hozzászóláshoz be kell jelentkezni
Ez nem működik.
- A hozzászóláshoz be kell jelentkezni
Csak úgy általában nem működik, vagy van valamilyen hibaüzenet vagy hibajelenség?
Szerk: esetleg a temporális file használata a gond?
fgrep -v -- "$f" "$file" >"$file.tmp" &&
mv -f -- "$file.tmp" "$file"
- A hozzászóláshoz be kell jelentkezni
Az lesz a gond ahogy most egy tesztfelületen megnéztem, hogy megcsinálja, csak nem írja bele a file-ba az értékeket. Viszont a második megoldásod temp file-al meg már értelmetlen, mert akkor az is kétsoros megoldés lesz, mint ahogy eredetileg megoldottam. Szerintem marad a sed, mert arra adtak jó megoldást, és érthető is a szintaktikája. Köszi a segítséget.
- A hozzászóláshoz be kell jelentkezni
Az jó, hogy megy, de azért emlékezzünk arra, hogy a sed mintaillesztést végez, a fgrep meg stringkeresést. Például az 'arb.c' minta ráillik arra, hogy 'arboc', de részstringént nincs benne.
- A hozzászóláshoz be kell jelentkezni
Igen, de mivel komplett útvonalak vannak/kerülnek bele a file-ba, ami ha egyezik törölni kell, és nem használok regexp-et keresésként, csak mplett sztringet, rész útvonal meg sosem kerül bele, így a sed-es megoldás tökéletesen működik. Most már 2 napja használom, sokféle esetben teszteltem, és rendben működik.
- A hozzászóláshoz be kell jelentkezni
Mert a tr nem regex alapú. Bizonyos patterneket elfogad a saját szintaxisában de az nem az extended re posix (ERE) vagy basic re posix (BRE) formátumú.
A sed ezeket támogatja.
Plusz itt sorok törléséről van szó vagyis az egész sort és a végén lévő esetleges új sor karakter(eket) is törölni kell. A sed "d" parancsa ezt csinálja, de a tr-nek nincsen fogalma arról hogy mi az a sor.
- A hozzászóláshoz be kell jelentkezni