Sortera och flytta filer

Här diskuterar vi skal, kommandon och klassiska linuxverktyg.
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Sortera och flytta filer

Inlägg av Substrata »

För konjunktion kan du pipe:a grep genom grep, alltså: ... | grep analogy | grep argument | ...

EDIT: Duktigt hjärnsläpp. :D Glöm ovanstående.

Däremot ska du kunna använda `grep -l analogy *' för att enbart lista filnamnen som innehåller "analogy", för (exempelvis) en senare pipe mot `xargs grep -l argument'. Grep är linjebaserat så för att söka efter två ord över en hel fil tror jag nog att du också behöver använda grep två gånger.

EDIT 2: Måste nog labba lite med Konservburks lösning. Tackar. :)
Användarvisningsbild
dmz
Inlägg: 3292
Blev medlem: 29 jul 2008, 19:42
OS: Arch Linux

Re: Sortera och flytta filer

Inlägg av dmz »

Substrata skrev:
Grep är linjebaserat så för att söka efter två ord över en hel fil tror jag nog att du också behöver använda grep två gånger.
Nejdå.

Kod: Markera allt

grep -P '(:?foo|bar|xap)' fil
ǁ A: Because it obfuscates the reading.
ǁ Q: Why is top posting so bad?
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Sortera och flytta filer

Inlägg av Konservburk »

dmz skrev:
Substrata skrev:
Grep är linjebaserat så för att söka efter två ord över en hel fil tror jag nog att du också behöver använda grep två gånger.
Nejdå.

Kod: Markera allt

grep -P '(:?foo|bar|xap)' fil
Jag är inte riktigt med på varför du använder -P i det här fallet?

Kod: Markera allt

       -P, --perl-regexp
              Interpret PATTERN as a Perl regular expression.  This is  highly
              experimental and grep -P may warn of unimplemented features.
Jag måste erkänna att jag har ganska dålig koll på perl-regexp, men :? matchar väl fortfarande noll eller ett : precis som vanligt? Så utan att testa så gissar jag att din kod plockar fram alla rader från fil som innehåller ett eller flera av orden :foo eller foo eller bar eller xap.

Men nu var det i det här fallet inte fråga om att hitta filer som innehåller något av orden, utan istället endast filer som faktiskt innehåller båda orden. Ett alternativ till att köra grep flera gånger skulle kunna vara något i stil med följande:

Kod: Markera allt

tr -d \\n fil | grep 'for.*bar\|bar.*foo'
Men den metoden blir dock snabbt väldigt komplicerad om antalet ord ökas. Du kanske
har någon bättre idé eller någon magisk perl-regexp på lut?
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Sortera och flytta filer

Inlägg av Substrata »

Är fullt medveten om att dmz kan besvara frågan; men (?: ...) används för att gruppera utan att fånga, så att man inte får back-references ala \1, $1 etc. I övrigt verkar dock "grep -P '(:?foo|bar|xap)'" fungera som "egrep 'foo|bar|xap' fil", alltså disjunktiv matchning; men nu när jag testat det så är det uppenbart att man kan använda det för att hitta filer som innehåller alla önskade ord (konjunktionen). Hela lösningen kräver dock mer jobb.
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Sortera och flytta filer

Inlägg av Substrata »

Men det är en intressant fråga hur man skriver en RE för konjunktiv matchning utan innebördes ordning. Något i stil med /(analogy.*argument)|(argument.*analogy)/ kan ju fungera, men det kräver att uttrycket matchas mot hela filen och inte rad för rad. Perl fixar det säkert utan hassel, men jag hittar vid en överblick inte en flagga till grep för det.
Användarvisningsbild
dmz
Inlägg: 3292
Blev medlem: 29 jul 2008, 19:42
OS: Arch Linux

Re: Sortera och flytta filer

Inlägg av dmz »

Substrata skrev:Är fullt medveten om att dmz kan besvara frågan; men (?: ...) används för att gruppera utan att fånga, så att man inte får back-references ala \1, $1 etc. I övrigt verkar dock "grep -P '(:?foo|bar|xap)'" fungera som "egrep 'foo|bar|xap' fil", alltså disjunktiv matchning; men nu när jag testat det så är det uppenbart att man kan använda det för att hitta filer som innehåller alla önskade ord (konjunktionen). Hela lösningen kräver dock mer jobb.
Precis. Man kan även göra saker i stil med /(?ifoobar)/, vilket då matchar
foobar och FOOBAR osv... rätt magiskt.
ǁ A: Because it obfuscates the reading.
ǁ Q: Why is top posting so bad?
Användarvisningsbild
dmz
Inlägg: 3292
Blev medlem: 29 jul 2008, 19:42
OS: Arch Linux

Re: Sortera och flytta filer

Inlägg av dmz »

Konservburk skrev:
Men den metoden blir dock snabbt väldigt komplicerad om antalet ord ökas. Du kanske
har någon bättre idé eller någon magisk perl-regexp på lut?
Jag skulle gjort något i stil med;

Kod: Markera allt

\cat foofile|perl -e '@c=<>;for(@c){print "\033[31m$_\033[0m" if /foo/ and /bar/;}' 
som då simulerar |grep foo|grep bar
ǁ A: Because it obfuscates the reading.
ǁ Q: Why is top posting so bad?
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Sortera och flytta filer

Inlägg av Substrata »

För att utveckla min tidigare frågeställning om konjunktiv matching mha disjunktiva uttryck; alltså om man vill matcha A, B och C i en text, utan innebördes ordning, så får man uttryck som ABC|ACB|BAC|BCA|CAB|CBA. I allmänhet ger n termer n! disjunktioner (O(n!)); så den här metoden bör kastas, omgående. :)

(Det verkar som att jag tenderar att missa Konservburks inlägg - ser nu att han har behandlat samma lösning.)
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Sortera och flytta filer

Inlägg av Substrata »

dmz skrev:Jag skulle gjort något i stil med;

Kod: Markera allt

\cat foofile|perl -e '@c=<>;for(@c){print "\033[31m$_\033[0m" if /foo/ and /bar/;}' 
som då simulerar |grep foo|grep bar
Det var länge sedan jag höll på med Perl, men om jag inte är ute och cyklar så läser du in en textfil till en array med en rad per element. I så fall hittar den rader som innehåller båda uttrycken, men missar om de är separerade över flera rader. Nu är ju den här delen av diskussion ett utskott från originalfrågan (som täckte fallet över flera rader), så jag säger inte att det spelar någon vidare roll. Men eftersom Perls RE:s kan matcha över flera rader, och eftersom man kan läsa in hela filen som en stor sträng, så blir nog också den lösningen lika enkel.
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Sortera och flytta filer

Inlägg av Konservburk »

Substrata skrev:men (?: ...) används för att gruppera utan att fånga, så att man inte får back-references ala \1, $1 etc.
Men nu var det ju :? och inte ?: i exemplet. För det är väl inte samma sak, eller?
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Sortera och flytta filer

Inlägg av Substrata »

Där sa du något. :) Vi får nog vänta tills dmz är tillbaka, för att få bekräftat om det var en typo. Hittar inget om (: ...) som särskild syntax i manualsidan. (? ...) är dock en del av den utökade syntaxen i Perls RE. Vid prov matchar den givna regexpen både ":foo" och "foo", och färgkodningen visar att kolonet är en del av matchningen; så din tidigare iaktagelse om att ? här har sin vanliga innebörd ser riktigt ut.
Användarvisningsbild
dmz
Inlägg: 3292
Blev medlem: 29 jul 2008, 19:42
OS: Arch Linux

Re: Sortera och flytta filer

Inlägg av dmz »

Konservburk skrev:
Substrata skrev:men (?: ...) används för att gruppera utan att fånga, så att man inte får back-references ala \1, $1 etc.
Men nu var det ju :? och inte ?: i exemplet. För det är väl inte samma sak, eller?
Stämmer, typo från min sida.

@Substrata: Tänker du på /m? Detta var ju faktiskt klurigare än vad
det såg ut vid en första anblick.
Då ska vi se om jag gör rätt den här gången då? ;D
my AND foo matchas:

Kod: Markera allt

> \cat readkey.pl -n|perl -e '$/=undef;$_=<>;print $_ if /my/ and /foo/;'       
     1	use strict;
     2	use Term::ReadKey;
     3	
     4	print "Enter char\n";
     5	ReadMode('cbreak');
     6	
     7	while(1) {
     8	  print "> ";
     9	  my $foo = ReadKey(0);
    10	  print "\n";
    11	  printf("%s => %d 0x%x \n", $foo, ord($foo), ord($foo));
    12	  
    13	}
my AND bar matchas INTE

Kod: Markera allt

> \cat readkey.pl -n|perl -e '$/=undef;$_=<>;print $_ if /my/ and /bar/;'
ǁ A: Because it obfuscates the reading.
ǁ Q: Why is top posting so bad?
Användarvisningsbild
Substrata
Inlägg: 71
Blev medlem: 13 apr 2010, 11:01
OS: Arch Linux
Utgåva: Vet inte/ingen utgåva passar

Re: Sortera och flytta filer

Inlägg av Substrata »

EDIT: Har rensat inlägget eftersom jag slarvläste dmz's inlägg. Koden fungerar ju utmärkt!
dmz skrev:Tänker du på /m?
perlre skrev:/m: Treat string as multiple lines. That is, change "^" and "$" from matching the start or end of the string to matching the start or end of any line anywhere within the string.
/s: Treat string as single line. That is, change "." to match any character whatsoever, even a newline, which normally it would not match.
Used together, as /ms, they let the "." match any character whatsoever, while still allowing "^" and "$" to match, respectively, just after and just before newlines within the string.
/s ser lämpligt ut här, om man behöver en RE som sträcker sig över flera rader mha .*. Men det stämmer bra att det var /m jag tänkte på. :)
Ainigma
Inlägg: 803
Blev medlem: 26 sep 2007, 20:49
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS

Re: Sortera och flytta filer

Inlägg av Ainigma »

Nu är det lite oklart för en oinitierad. :D Är det olika varianter av konserburks förslag (som fungerade utmärkt), eller är det något utöver det ni försöka åstadkomma nu?
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Sortera och flytta filer

Inlägg av Konservburk »

Ainigma skrev:Nu är det lite oklart för en oinitierad. :D Är det olika varianter av konserburks förslag (som fungerade utmärkt), eller är det något utöver det ni försöka åstadkomma nu?
Vi är nog inne på överkurs. Det är det intressanta delproblemet att endast matcha filer som innehåller båda orden som vi har fördjupat oss i.
Ainigma
Inlägg: 803
Blev medlem: 26 sep 2007, 20:49
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS

Re: Sortera och flytta filer

Inlägg av Ainigma »

Ok, och om jag nu vill göra ett skript av konsverburks förslag, hur gör jag enklast då? :)
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Sortera och flytta filer

Inlägg av Konservburk »

Ainigma skrev:Ok, och om jag nu vill göra ett skript av konsverburks förslag, hur gör jag enklast då? :)
Släng in det hela i en fil och lägga till #!/bin/sh längst upp:

Kod: Markera allt

#!/bin/sh
exec find -maxdepth 1 \
-exec sh -c 'file -i "$0" 2>&-| grep -q application/pdf' {} \; \
-exec sh -c 'pdftotext "$0" - 2>&-| grep -qi analogy' {} \; \
-exec sh -c 'pdftotext "$0" - 2>&-| grep -qi argument' {} \; \
-exec mv {} en_egen_mapp/ \;
Lägg förslagsvis filen i katalogen ~/bin/ och glöm inte att göra skriptet körbart:

Kod: Markera allt

chmod +x ~/bin/skriptet.sh
Ainigma
Inlägg: 803
Blev medlem: 26 sep 2007, 20:49
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS

Re: Sortera och flytta filer

Inlägg av Ainigma »

Jag har försökt göra ett sådant där skript nu. Ni får ha överseende med min okunnighet men jag vet inte hur jag nu ska använda det. Är det tänkt att det ska vara tillgänglig via ett högerklick (hur man nu gör det) så att när en mapp innehåller filer jag vill sortera så ska jag högerklicka och så att säga applicera skriptet på mappen, eller hur bör jag använda det? (Har knappt använt skript förut) :P
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: Sortera och flytta filer

Inlägg av Konservburk »

Ainigma skrev:Jag har försökt göra ett sådant där skript nu. Ni får ha överseende med min okunnighet men jag vet inte hur jag nu ska använda det. Är det tänkt att det ska vara tillgänglig via ett högerklick (hur man nu gör det) så att när en mapp innehåller filer jag vill sortera så ska jag högerklicka och så att säga applicera skriptet på mappen, eller hur bör jag använda det? (Har knappt använt skript förut) :P
Det låter som att du vill ha ett nautilus-skript (ett specialfall av ett vanligt skript). Flytta då skript-filen till katalogen ~/.gnome2/nautilus-scripts/ och så vill du förmodligen lägga till "$@" (med fnuttar och allt) direkt efter find.
Ainigma
Inlägg: 803
Blev medlem: 26 sep 2007, 20:49
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS

Re: Sortera och flytta filer

Inlägg av Ainigma »

så vill du förmodligen lägga till "$@" (med fnuttar och allt) direkt efter find.
Du menar alltså:

#!/bin/sh
exec find "$@" -maxdepth 1 \
-exec sh -c 'file -i "$0" 2>&-| grep -q application/pdf' {} \; \
-exec sh -c 'pdftotext "$0" - 2>&-| grep -qi analogy' {} \; \
-exec sh -c 'pdftotext "$0" - 2>&-| grep -qi argument' {} \; \
-exec mv {} en_egen_mapp/ \;

? :)
Skriv svar

Återgå till "Terminalforum"