bash spara till variable funkar ej || hur kan jag göra det så det funkar?

Trädvy Permalänk
Medlem
Registrerad
Sep 2009

bash spara till variable funkar ej || hur kan jag göra det så det funkar?

Hej sitter lite med ett bash skript så vill jag funga en viss typ av fil via ls se koden nedan:

vid=ls | grep '.mov\|.mpeg4\|.avi\|.wmv\|.mpegps\|.flv\|.3gpp\|.webm\|.mp4\|.mkv'

jag har googlat lite för att hitta en lösning fick för mig att detta skulle funger (vilket det inte gjorde):

vid=${ls | grep '.mov\|.mpeg4\|.avi\|.wmv\|.mpegps\|.flv\|.3gpp\|.webm\|.mp4\|.mkv'}

Någon som har något förslag på hur man kan lösa detta?

Tack för svar!

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Trädvy Permalänk
Medlem
Registrerad
Jun 2013

Nära! Men det ska vara vanliga parenteser,

vid=$(ls | grep '.mov\|.mpeg4\|.avi\|.wmv\|.mpegps\|.flv\|.3gpp\|.webm\|.mp4\|.mkv')

Utan backslash matchar en punkt allt, så det kan vara bra att ändra. Sen är det nog bra att sluta regexen med $, så det faktiskt är filändelsen vi matchar på. För att slippa repetera \. och $ för varje ändelse kan man använda en grupp,

vid=$(ls | grep '\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)$')

Se till att testa scriptet med filnamn som innehåller mellanslag, det kan krångla om man inte har citattecken på de rätta ställena. Egentligen ska man använda find till det här och inte ls, då går det även att hantera filnamn med radbrytning.

Trädvy Permalänk
Medlem
Registrerad
Sep 2009

Grymt!

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Apr 2013

@asdfgh: Det korrekta kommandot är

find | grep '\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)$'

alias medialist="find | grep '\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)$'"

gör att du bara behöver skriva medialist för att utföra kommandot

För att göra kommandot permanent för en användare lägg det i filen /home/USERNAME/.bashrc och logga ut/in igen.
För att göra kommandot permanent för alla användare lägg det i filen /etc/bashrc och starta om datorn.

Server: AMD Ryzen 7 1800X 8/16 | ASUS Crosshair VI hero | 64 GB Corsair RAM @3000 MHz | ASUS radeon RX 460 2GB | Samsung 960 PRO 512 GB M.2 | 2x 2 TB Samsung 850 PRO SSD | 6x Seagate 10 TB | NEC PA301W @ 2560x1600 | Linux Mint 19 Cinnamon

Trädvy Permalänk
Forumledare
Registrerad
Okt 2002

Både find och ls är vanskliga att ha i pipes pga förekomsten av oväntade filnamn. Ofta räcker det med ett mellanslag för att fälla oförsiktiga försök, och lägger man till att filnamn utan vidare kan innehålla radbrytningar och annat så faller de flesta övriga.

För att undvika sådana problem så bör man helt undvika att använda ls på detta sätt, och gärna vara medveten om de nullterminerade varianterna av coreutils så som find -print0, xargs -0, grep -Z, etc.

Om man bara är ute efter att filtrera filnamn så går det dock oftast att efter plöjande av manualen få find att göra vad man vill direkt, vilket undviker all problematik:

find -type f -iregex '.*\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)'

En process mindre än tidigare förslag, och det undviker framför allt att skicka potentiellt problematiska filnamn genom en pipe (se sektionen "UNUSUAL FILENAMES" i manualen till GNU find). i:et gör det skiftlägesokänsligt, dvs både .MOV och .mov (och .MoV, och …) träffas. find gör sig ofta väldigt bra för liknande saker då man direkt kan utföra kommandon på filerna med dess -exec-kommandon.

Faktum är att man även kan göra denna globbning direkt i Bash med hjälp av extglob, globstar och för extrapoäng även nocaseglob:

shopt -s extglob globstar nocaseglob ls **/*.@(mov|mpeg4|avi|wmv|mpegps|flv|3gpp|webm|mp4|mkv)

Om man vill fånga filerna och göra något mer avancerat än vad find -exec tillåter så är denna globb också det mest robusta sättet att fånga filerna i fråga (for i in …), och behöver inte ens skapa en enda ny process, om vi antar att vi redan kör Bash.

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Trädvy Permalänk
Medlem
Registrerad
Sep 2009
Skrivet av phz:

find -type f -iregex '.*\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)'

när jag använder find så här funkar det så länge jag inte sätter det till en variabel dvs:

$ find -type f -iregex '.*\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)' # ger output filen jag är ute efter. $ vid=find -type f -iregex '.*\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)' # ger outputen nedan:

No command '-mtype' found, did you mean: Command 'mtype' from package 'mtools' (main) -mtype: command not found

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Trädvy Permalänk
Forumledare
Registrerad
Okt 2002
Skrivet av asdfgh:

när jag använder find så här funkar det så länge jag inte sätter det till en variabel dvs:

$ find -type f -iregex '.*\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)' # ger output filen jag är ute efter. $ vid=find -type f -iregex '.*\.\(mov\|mpeg4\|avi\|wmv\|mpegps\|flv\|3gpp\|webm\|mp4\|mkv\)' # ger outputen nedan:

No command '-mtype' found, did you mean: Command 'mtype' from package 'mtools' (main) -mtype: command not found

Det är inte så du tilldelar variabler från kommandooutput, men även om man säger att du behöver $() runt högerledet så blir det ett dåligt sätt att samla filnamn, så framför allt: vad är det du försöker göra? Det är sällan "rätt" att samla en lista med filnamn i en mellanvariabel: bättre är att direkt globba fram filnamn att loopa över eller använda find -exec om det är något externt kommando du tänkt köra med filnamnen som argument.

I Bash kan man även ekvivalent lagra filnamn i en array som man sedan kan operera på, men oftast är det bara att loopa direkt över ett globuttryck.

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Trädvy Permalänk
Medlem
Registrerad
Sep 2009

Jag kommer bara ha en specifik video fil i samma mapp som scriptet körs i. Denna fil vill jag dels få reda på vad den har för "typ" och dels veta va den heter (då det kan komma att vara okänt innan) sedan konverteras det till ett annat fil video format (eller så är tanken iaf).

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6