Linux/Ubuntu filecopy script vraag

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • KillerAce_NL
  • Registratie: Juni 2001
  • Niet online

KillerAce_NL

If it ain't broke...

Topicstarter
Ik heb een maindir met daarin allerlei subdirs, ik ben geinteresseerd in de subdirs die beginnen met ABCD en die daarna van naam verschillen, met als bonus dat er ook nog eens spaties in de subdir naam staan.
Die wil ook doorzoeken op de aanwezigheid van bestand abcd.jpg. Als deze aanwezig is dan dient, de aanwezige file dus naar de (child) subsubdirs gekopieerd te worden en dan dit voor elke folder die voldoet.
Elke subdir heeft dus zijn eigen unieke abcd.jpg die naar zijn childfolders gekopieerd moet worden.
Dit zijn er vele te veel om handmatig te doen. Ik ben dus op zoek naar iets scripted dat via terminal onder Ubuntu kan.

Maindir
----------subdir “ABCD*” (met daarin abcd.jpg)
--------------------------------subsubdir1 (hier moet een kopie van abcd.jpg naartoe)
--------------------------------subsubdir2 (hier moet een kopie van abcd.jpg naartoe)

Ik heb al e.e.a. geprobeerd, maar ben echt nieuw met Ubuntu. een file zoeken lukt wel (de dirs met masker ABCD doorzoeken niet), normaal zou ik onder Windows wel iets kunnen met powershell en een foreach commando, maar ik kom er gewoon niet uit.

Kan iemand mij helpen ?

Beste antwoord (via KillerAce_NL op 29-08-2022 16:52)


  • MartinMeijerink
  • Registratie: Juli 2008
  • Laatst online: 09:20

MartinMeijerink

Niet van deze wereld

Het kan heel simpel, met deze one-liner, die je start vanuit je maindir:
for i in ABCD*/abcd.jpg;do for j in "${i%%/*}/"*;do test -d "$j" && cp -af "$i" "$j";done;done


In de praktijk:
Afbeeldingslocatie: https://tweakers.net/i/9XNDjYgoI1GhpDlJrHYo8kjISmg=/full-fit-in/4000x4000/filters:no_upscale():fill(white):strip_exif()/f/image/cCTxpUSXUAghB4LB6N9x8p2D.png?f=user_large

An unbreakable toy is useful to break other toys

Alle reacties


Acties:
  • +2 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
Het find commando is een mooi startpunt.
Lees de manpage, zoek naar voorbeelden op internet en kijk hoe ver je komt.

Ben ik nou zo dom of zijn jullie nou zo slim?


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:18

Hero of Time

Moderator LNX

There is only one Legend

Voor Linux is er ook Powershell beschikbaar, als je dat prettiger vind.

Maar je hebt een map met als naam 'foobar', waarin een bestand foo.jpg staat. Die foo.jpg wil je dan naar de submappen hebben. Het zou dan al zo simpel kunnen zijn als 'cp foo.jpg */' per subdir die je wilt behandelen, maar dat kan wat veel handwerk zijn als er veel mappen zijn om doorheen te gaan.

Andere optie is zoals hierboven aangegeven wordt via find. Test het dan wel eerst met een kleine set aan mappen zodat je zeker weet dat je selectie en bestemming kloppen.

Commandline FTW | Tweakt met mate


Acties:
  • 0 Henk 'm!

  • KillerAce_NL
  • Registratie: Juni 2001
  • Niet online

KillerAce_NL

If it ain't broke...

Topicstarter
Ik heb al e.e.a. nagekeken en met find kan ik iig al de subdirs lsiten die aan mijn search voldoen.
Nu moet ik dat weer als basis nemen om te doorzoeken op file abcd.jpg en dan voor elke line de gevonden abcd.jpg naar de child dirs van de subdir waarin die jpg staat kopieren.

Kun je dat pipen, heeft 1 van jullie daar een voorbeeld van, ik weet gewoon ff niet waarop ik moet zoeken.

Acties:
  • 0 Henk 'm!

  • Jazzy
  • Registratie: Juni 2000
  • Laatst online: 23:02

Jazzy

Moderator SSC/PB

Moooooh!

Zou het lekker met PowerShell doen als ik jou was. Moet niet heel moeilijk zijn om je directories in een array te zetten, die dan door te lopen en in elke instance je ding te doen. Kun je in ieder geval gewoon met objecten werken en hoef je geen tekst te parsen.

Exchange en Office 365 specialist. Mijn blog.


Acties:
  • +1 Henk 'm!

  • deHakkelaar
  • Registratie: Februari 2015
  • Laatst online: 27-07-2024
$ nano script.sh
#!/bin/bash
rootdir="/tmp/maindir/"
searchname="abcd.jpg"

filenames=$(find "${rootdir}" -mindepth 2 -maxdepth 2 -type f -name "${searchname}")
while read filename; do
  subdir=$(dirname "${filename}")
  subsubdirs=$(find "${subdir}" -mindepth 1 -maxdepth 1 -type d)

  # Below one prints to screen instead of copying
  xargs -r -n 1 -d "\n" echo "cp -p ${filename}" <<< "${subsubdirs}"

  # Below one actually copies instead of printing to screen
  # xargs -r -n 1 -d "\n" cp -p "${filename}" <<< "${subsubdirs}"

done <<< "${filenames}"
exit 0

$ chmod +x script.sh
$

$ tree /tmp/maindir/
/tmp/maindir/
├── ABCD1
│   ├── abcd.jpg
│   ├── subsubdir1
│   └── subsubdir2
├── ABCD2
│   ├── abcd.jpg
│   ├── subsubdir1
│   ├── subsubdir2
│   └── subsubdir3
└── ABCD 3
    ├── abcd.jpg
    ├── subsubdir1
    ├── subsubdir2
    ├── subsubdir3
    └── subsubdir4

$ ./script.sh | sort
cp -p /tmp/maindir/ABCD1/abcd.jpg /tmp/maindir/ABCD1/subsubdir1
cp -p /tmp/maindir/ABCD1/abcd.jpg /tmp/maindir/ABCD1/subsubdir2
cp -p /tmp/maindir/ABCD2/abcd.jpg /tmp/maindir/ABCD2/subsubdir1
cp -p /tmp/maindir/ABCD2/abcd.jpg /tmp/maindir/ABCD2/subsubdir2
cp -p /tmp/maindir/ABCD2/abcd.jpg /tmp/maindir/ABCD2/subsubdir3
cp -p /tmp/maindir/ABCD 3/abcd.jpg /tmp/maindir/ABCD 3/subsubdir1
cp -p /tmp/maindir/ABCD 3/abcd.jpg /tmp/maindir/ABCD 3/subsubdir2
cp -p /tmp/maindir/ABCD 3/abcd.jpg /tmp/maindir/ABCD 3/subsubdir3
cp -p /tmp/maindir/ABCD 3/abcd.jpg /tmp/maindir/ABCD 3/subsubdir4

$ nano script.sh
[..]
  # Below one prints to screen instead of copying
  # xargs -r -n 1 -d "\n" echo "cp -p ${filename}" <<< "${subsubdirs}"

  # Below one actually copies instead of printing to screen
  xargs -r -n 1 -d "\n" cp -p "${filename}" <<< "${subsubdirs}"
[..]

$ ./script.sh
$

$ tree /tmp/maindir/
/tmp/maindir/
├── ABCD1
│   ├── abcd.jpg
│   ├── subsubdir1
│   │   └── abcd.jpg
│   └── subsubdir2
│       └── abcd.jpg
├── ABCD2
│   ├── abcd.jpg
│   ├── subsubdir1
│   │   └── abcd.jpg
│   ├── subsubdir2
│   │   └── abcd.jpg
│   └── subsubdir3
│       └── abcd.jpg
└── ABCD 3
    ├── abcd.jpg
    ├── subsubdir1
    │   └── abcd.jpg
    ├── subsubdir2
    │   └── abcd.jpg
    ├── subsubdir3
    │   └── abcd.jpg
    └── subsubdir4
        └── abcd.jpg

Zorg voor een goede backup eerst!

[ Voor 197% gewijzigd door deHakkelaar op 25-08-2022 22:49 . Reden: while done ipv for do ivm spaties plus geen lege xargs runs plus cp -p argument ]

There are only 10 types of people in the world: those who understand binary, and those who don't


Acties:
  • +3 Henk 'm!

  • deHakkelaar
  • Registratie: Februari 2015
  • Laatst online: 27-07-2024
Moest ff opzoeken wat Powershell voor Linux betekende.
He ba wat vies ;)

There are only 10 types of people in the world: those who understand binary, and those who don't


Acties:
  • +1 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:18

Hero of Time

Moderator LNX

There is only one Legend

Jazzy schreef op dinsdag 23 augustus 2022 @ 11:22:
Zou het lekker met PowerShell doen als ik jou was. Moet niet heel moeilijk zijn om je directories in een array te zetten, die dan door te lopen en in elke instance je ding te doen. Kun je in ieder geval gewoon met objecten werken en hoef je geen tekst te parsen.
Als je heer en meester bent met Powershell, prima. Maar het kan ook gewoon met Bash e.d. Heck, je zou het zelfs met Python of van mij part Perl of Ruby doen als je echt gek wilt doen. :P

Soms is het prettiger/makkelijker/duidelijker om met tekst te maken te hebben dan met objecten. Want met Powershell heb ik ook wel eens gevloekt waarom ik een idiote uitvoer krijg en dan blijkt het een of ander object te zijn, ipv als je het los opvraagt, het een string laat zien. Wat dan eigenlijk een object is en dus anders behandeld moet worden.

Commandline FTW | Tweakt met mate


Acties:
  • Beste antwoord
  • +7 Henk 'm!

  • MartinMeijerink
  • Registratie: Juli 2008
  • Laatst online: 09:20

MartinMeijerink

Niet van deze wereld

Het kan heel simpel, met deze one-liner, die je start vanuit je maindir:
for i in ABCD*/abcd.jpg;do for j in "${i%%/*}/"*;do test -d "$j" && cp -af "$i" "$j";done;done


In de praktijk:
Afbeeldingslocatie: https://tweakers.net/i/9XNDjYgoI1GhpDlJrHYo8kjISmg=/full-fit-in/4000x4000/filters:no_upscale():fill(white):strip_exif()/f/image/cCTxpUSXUAghB4LB6N9x8p2D.png?f=user_large

An unbreakable toy is useful to break other toys


Acties:
  • +2 Henk 'm!

  • deHakkelaar
  • Registratie: Februari 2015
  • Laatst online: 27-07-2024
MartinMeijerink schreef op dinsdag 23 augustus 2022 @ 19:53:
for i in ABCD*/abcd.jpg;do for j in "${i%%/*}/"*;do test -d "$j" && cp -af "$i" "$j";done;done
Ik zou wel eerst een "dry run" doen eg:
code:
1
for i in ABCD*/abcd.jpg; do for j in "${i%%/*}/"*; do test -d "$j" && echo "cp -af ${i} ${j}"; done; done

@KillerAce_NL , ik heb boven mijn scriptje nog een klein beetje aangepast voor uitzonderingen.
Oa doet xargs geen run meer als geen argumenten worden aangeleverd (-r argument).
En wat specifieker -mindepth & -maxdepth aangepast zodat niet in subsubsubdir's etc wordt geïtereerd.

[ Voor 5% gewijzigd door deHakkelaar op 24-08-2022 00:52 ]

There are only 10 types of people in the world: those who understand binary, and those who don't


Acties:
  • 0 Henk 'm!

  • deHakkelaar
  • Registratie: Februari 2015
  • Laatst online: 27-07-2024
@MartinMeijerink , ik denk dat je jouw one-liner moet uitvoeren als root user wil je de file attributes behouden met de cp -p voor "preserve"?
Zelfde geld voor mijn script als je daar cp -p van maakt.

EDIT:
$ tree /tmp/maindir/
/tmp/maindir/
├── ABCD1
│   ├── abcd.jpg
│   ├── subsubdir1
│   └── subsubdir2
├── ABCD2
│   ├── abcd.jpg
│   ├── subsubdir1
│   ├── subsubdir2
│   └── subsubdir3
│       └── subsubsubdir
│           └── abcd.jpg
├── ABCD 3
│   ├── abcd.jpg
│   ├── subsubdir1
│   ├── subsubdir2
│   ├── subsubdir 3
│   └── subsubdir 4
└── abcd.jpg

$ ./script.sh | sort
cp /tmp/maindir/ABCD1/abcd.jpg /tmp/maindir/ABCD1/subsubdir1
cp /tmp/maindir/ABCD1/abcd.jpg /tmp/maindir/ABCD1/subsubdir2
cp /tmp/maindir/ABCD2/abcd.jpg /tmp/maindir/ABCD2/subsubdir1
cp /tmp/maindir/ABCD2/abcd.jpg /tmp/maindir/ABCD2/subsubdir2
cp /tmp/maindir/ABCD2/abcd.jpg /tmp/maindir/ABCD2/subsubdir3
cp /tmp/maindir/ABCD 3/abcd.jpg /tmp/maindir/ABCD 3/subsubdir1
cp /tmp/maindir/ABCD 3/abcd.jpg /tmp/maindir/ABCD 3/subsubdir2
cp /tmp/maindir/ABCD 3/abcd.jpg /tmp/maindir/ABCD 3/subsubdir 3
cp /tmp/maindir/ABCD 3/abcd.jpg /tmp/maindir/ABCD 3/subsubdir 4

[ Voor 73% gewijzigd door deHakkelaar op 24-08-2022 02:07 ]

There are only 10 types of people in the world: those who understand binary, and those who don't


Acties:
  • +1 Henk 'm!

  • Jazzy
  • Registratie: Juni 2000
  • Laatst online: 23:02

Jazzy

Moderator SSC/PB

Moooooh!

Hero of Time schreef op dinsdag 23 augustus 2022 @ 19:08:
[...]

Als je heer en meester bent met Powershell, prima. Maar het kan ook gewoon met Bash e.d. Heck, je zou het zelfs met Python of van mij part Perl of Ruby doen als je echt gek wilt doen. :P
Absoluut, als je het echt leuk vindt zou het ook nog wel in assembly kunnen. :) In dit geval weet de TS hoe het te doen in PowerShell maar realiseert zich blijkbaar niet dat PowerShell gewoon gebruikt kan worden. Scheelt veel tijd als je je bestaande skills kunt gebruiken ipv. nieuwe vaardigheden aanleren die je waarschijnlijk maar beperkt gaat gebruiken.

Nu heeft de TS mazzel dat hij het voorgekauwd op een presenteerblaadje krijgt, maar om het te begrijpen moet je dus verdiepen in o.a.:
- gebruik van variabelen
- aantal opties van find
- gebruik van xargs om een cmdline te bouwen
- gebruk van <<< om een string aan te voeren

Anyway, is dus gewoon een kwestie van gebruiken wat je al weet of iets nieuws leren om hetzelfde doel te bereiken.
Soms is het prettiger/makkelijker/duidelijker om met tekst te maken te hebben dan met objecten. Want met Powershell heb ik ook wel eens gevloekt waarom ik een idiote uitvoer krijg en dan blijkt het een of ander object te zijn, ipv als je het los opvraagt, het een string laat zien. Wat dan eigenlijk een object is en dus anders behandeld moet worden.
Dat zal een kwestie van kennis en ervaring zijn. Heb zelf ervaring met shelscripting (ksh op AIX in een ver verleden) en PowerShell en vind object > text. Maar dat is een andere discussie.

Exchange en Office 365 specialist. Mijn blog.


Acties:
  • +1 Henk 'm!

  • MartinMeijerink
  • Registratie: Juli 2008
  • Laatst online: 09:20

MartinMeijerink

Niet van deze wereld

deHakkelaar schreef op woensdag 24 augustus 2022 @ 01:21:
@MartinMeijerink , ik denk dat je jouw one-liner moet uitvoeren als root user wil je de file attributes behouden met de cp -p voor "preserve"?
Nee, hoeft niet als root, tenzij je de owner ook wilt behouden.

An unbreakable toy is useful to break other toys


Acties:
  • +2 Henk 'm!

  • deHakkelaar
  • Registratie: Februari 2015
  • Laatst online: 27-07-2024
@MartinMeijerink , ja ik doelde idd op ownership welke niet mee wordt gecopieerd met het -p argument zonder sudo/root powers.
Ik neem aan dat de folders en bestanden onderdeel zijn van bv een Samba share of een web folder waar je deze ownership wilt behouden ipv achteraf de gecopieerde bestanden weer aanpassen met chown.

EDIT:
$ man cp
[..]
       -p     same as --preserve=mode,ownership,timestamps

       --preserve[=ATTR_LIST]
              preserve  the  specified  attributes  (default:  mode,owner‐
              ship,timestamps), if possible  additional  attributes:  con‐
              text, links, xattr, all

Ik heb dit argument maar ook toegevoegd in mijn scriptje boven.

[ Voor 35% gewijzigd door deHakkelaar op 25-08-2022 22:50 ]

There are only 10 types of people in the world: those who understand binary, and those who don't


Acties:
  • +2 Henk 'm!

  • KillerAce_NL
  • Registratie: Juni 2001
  • Niet online

KillerAce_NL

If it ain't broke...

Topicstarter
@allen:
Bedankt voor de hulp. Door omstandigheden kan ik er helaas nu even niet mee verder. Volgende week hoop ik dit op te pakken en laat ik van me horen.
Voor nu fijn weekend !

Acties:
  • +1 Henk 'm!

  • KillerAce_NL
  • Registratie: Juni 2001
  • Niet online

KillerAce_NL

If it ain't broke...

Topicstarter
MartinMeijerink schreef op dinsdag 23 augustus 2022 @ 19:53:
Het kan heel simpel, met deze one-liner, die je start vanuit je maindir:
for i in ABCD*/abcd.jpg;do for j in "${i%%/*}/"*;do test -d "$j" && cp -af "$i" "$j";done;done


In de praktijk:
[Afbeelding]
Uiteindelijk deze weg gekozen, wel nog een isse met de mapnamen, maar daar heb ik een compromis in gesloten. (ging toch niet goed met b.v. mapnaam " ABCDblblabla blabla blabla".
Volgende keer sla ik denk ik toch de powershell weg in.

Acties:
  • 0 Henk 'm!

  • MartinMeijerink
  • Registratie: Juli 2008
  • Laatst online: 09:20

MartinMeijerink

Niet van deze wereld

Ook dan werkt het, of begrijp ik het niet goed?
Afbeeldingslocatie: https://tweakers.net/i/dAvAJ31U2L7tiqVlKyrDzlw41kk=/full-fit-in/4000x4000/filters:no_upscale():fill(white):strip_exif()/f/image/UOVpUqnHZHrM1sIEhv8XFdEB.png?f=user_large

An unbreakable toy is useful to break other toys


Acties:
  • +2 Henk 'm!

  • vanaalten
  • Registratie: September 2002
  • Laatst online: 19-08 21:45
MartinMeijerink schreef op maandag 29 augustus 2022 @ 19:06:
Ook dan werkt het, of begrijp ik het niet goed?
[Afbeelding]
Off-topic, maar bedankt: het 'tree' commando kende ik nog niet! 25 jaar werken met Linux en nog steeds leer je nieuwe dingen... :)

Acties:
  • +1 Henk 'm!

  • deHakkelaar
  • Registratie: Februari 2015
  • Laatst online: 27-07-2024
@vanaalten , het tree commando was 1 vd eerste commandos die mij geleerd werdt op school met Unix lessen.
Deze zit in de tree package voor Debian/Pi-OS en wordt niet voor elke distro OOTB geinstalleerd:
$ dpkg -S $(readlink -f $(which tree))
tree: /usr/bin/tree

Ik leer ook steeds weer wat nieuws na zoveel jaren ;)

There are only 10 types of people in the world: those who understand binary, and those who don't


Acties:
  • 0 Henk 'm!

  • deHakkelaar
  • Registratie: Februari 2015
  • Laatst online: 27-07-2024
KillerAce_NL schreef op maandag 29 augustus 2022 @ 16:53:
ging toch niet goed met b.v. mapnaam " ABCDblblabla blabla blabla".
Had je dan niet eerst een "dry run" gedaan om te kijken ofdat goed gaat?
EDIT: Dan had de one-liner of mijn scriptje nog aangepast kunnen worden ipv met Powershell opnieuw het wiel uitvinden.

[ Voor 18% gewijzigd door deHakkelaar op 30-08-2022 18:20 . Reden: oa typo ]

There are only 10 types of people in the world: those who understand binary, and those who don't


Acties:
  • 0 Henk 'm!

  • Jazzy
  • Registratie: Juni 2000
  • Laatst online: 23:02

Jazzy

Moderator SSC/PB

Moooooh!

vanaalten schreef op dinsdag 30 augustus 2022 @ 08:07:
[...]

Off-topic, maar bedankt: het 'tree' commando kende ik nog niet! 25 jaar werken met Linux en nog steeds leer je nieuwe dingen... :)
Die was heel ver weggezakt! Herinner me het commando uit MS-DOS 3.nogwat tijd, toen werken met directories nog relatief nieuw was. Nooit geweten dat het ook naar *nix geport was.

(Enigzins) on-topic: Moest gisteren een loopje maken die een bepaald aantal keren herhaalt, zat te denken hoe de syntax ook alweer is en het enige wat me te binnen schoot was FOR I=1 TO 10 ... NEXT I. Is gewoon MSX BASIC waar ik eind jaren 80 in programmeerde en al zeker 30 jaar niet meer gebruikt heb. Maar de juiste syntax of wat ik gisteren gegeten heb kan ik me niet herinneren. :)

[ Voor 30% gewijzigd door Jazzy op 30-08-2022 20:36 ]

Exchange en Office 365 specialist. Mijn blog.


Acties:
  • 0 Henk 'm!

  • Hero of Time
  • Registratie: Oktober 2004
  • Laatst online: 22:18

Hero of Time

Moderator LNX

There is only one Legend

De vraag van de TS is beantwoord. Laten we nou niet het topic kapen en allerlei off-topic oude koeien uit de sloot halen voor nostalgie.

Commandline FTW | Tweakt met mate

Pagina: 1