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

Permalänk
Medlem

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!

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
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

Permalänk

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.

Permalänk
Medlem

Grymt!

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
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

Permalänk
Medlem

@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.

Visa signatur

Server: Fractal design Define 7 XL | AMD Ryzen 7 5800X 8/16 | ASUS ROG CROSSHAIR VIII DARK HERO | 64GB Corsair @ 3000MHz | ASUS Radeon RX 460 2GB | Samsung 960 PRO 512 GB M.2 | 2x 2TB Samsung 850 PRO SSD | 6x Seagate Ironwolf Pro 10TB
WS: Phantex Entoo Elite | AMD Ryzen Threadripper 1950X 16/32 | ASUS Zenith extreme | 128GB G.Skill @ 2400MHz | ASUS Radeon HD7970 | 3x 2TB Samsung 960PRO M.2 | 6x Seagate Ironwolf Pro 10 TB
NEC PA301W 30" @ 2560x1600 | Linux Mint 21.3 Cinnamon

Permalänk
Hedersmedlem

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.

Visa signatur

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

Permalänk
Medlem
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

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
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

Permalänk
Hedersmedlem
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.

Visa signatur

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

Permalänk
Medlem

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).

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
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