Portál AbcLinuxu, 10. května 2024 22:53


Dotaz: procházení adresářů a kopírování souborů a jejich přejmenování jinam

23.11.2018 10:42 Honza
procházení adresářů a kopírování souborů a jejich přejmenování jinam
Přečteno: 398×
Odpovědět | Admin
Mám adresáře A1-A12, B1-B12 atd. a v každém je soubor s názvem "assembly.fa", ale jeho obsah je v každém adresáři jiný. Potřebuji tyto soubory překopírovat třeba do /home s tím, že se soubor přejmenuje podle názvu adresáře. Tj. z adresáře A1 se bude jmenovat A1assembly.fa atd.. Nezvládl by někdo script, který to udělá? Přiznávám, že programovat neumím, tak píšu sem. Díky

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

23.11.2018 11:12 debian+
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Odpovědět | | Sbalit | Link | Blokovat | Admin
Obsahuj adresare medzeru?
Řešení 1× (Filip Jirsák)
23.11.2018 11:20 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Odpovědět | | Sbalit | Link | Blokovat | Admin
cd '/zdrojový/adresář'
for dir in {A..B}{1..12}; do
  cp "${dir}/assembly.fa" '/cílový/adresář/'"${dir}assembly.fa"
done
23.11.2018 11:29 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam

Tohle^^^ tedy samozřejmě předpokládá, že jsou všechny ty adresáře v jednom a tom samém společném adresáři. Tady je jednoduchý ilustrativní příklad / test:

mkdir nějaký_pokus cíl
cd nějaký_pokus
mkdir {A..B}{1..12}
touch {A..B}{1..12}/assembly.fa
cd ..
for dir in {A..B}{1..12}; do
  cp "nějaký_pokus/${dir}/assembly.fa" "cíl/${dir}assembly.fa"
done
ls -l cíl
rm -Rf nějaký_pokus cíl
23.11.2018 11:49 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam

Pokud ty adresáře můžou být libovolně vnořené v jiných adresářích, tak třeba takto:

find zdroj -type d -regextype awk -regex '.*[AB](1[0-2]?|[2-9])' \
| while read dir; do
    cp "${dir}/assembly.fa" "cíl/$(basename "${dir}")assembly.fa"
  done

Opět ukázka s triviálním testem (která sice netestuje hlubší zanoření adresářů, protože jsem extrémně líný, ale mělo by to i s hlubším zanořením fungovat):

mkdir 'zdroj' 'cíl'
mkdir 'zdroj/'{A..B}{1..12}
touch 'zdroj/'{A..B}{1..12}'/assembly.fa'
find zdroj -type d -regextype awk -regex '.*[AB](1[0-2]?|[2-9])' \
| while read dir; do
    cp "${dir}/assembly.fa" "cíl/$(basename "${dir}")assembly.fa"
  done
ls -l 'cíl'
rm -Rf 'zdroj' 'cíl'
23.11.2018 12:44 Honza
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Perfektní, funguje to. Ušetří mě to případných chyb při otravném ručním přepisování. Díky moc!
23.11.2018 11:34 debian+
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Odpovědět | | Sbalit | Link | Blokovat | Admin
Skopiruj, prepis do terminalu a na zaciatku prikazu si nastav premenna (dopis do uvodzoviek), ze z kadial (odkial) a kam ma skopirovat. A medzera nesmie byt v nazve KAM a Z (ak by treba, povedz, osetrim). V ich podadresarov moze.
KAM=""; Z=""; find $Z -name "assembly.fa" -exec echo "cp -v '{}' $KAM/\'\`echo {}|tr / _\`\'" \; |bash
A u mna "demo" (pouzil som absolutne cesty, mozes pouzit i relativne):
$ KAM="/tmp/kam"; Z="/tmp/z/"; find $Z -name "assembly.fa" -exec echo "cp -v '{}' $KAM/\'\`echo {}|tr / _\`\'" \; |bash 
'/tmp/z/b/assembly.fa' -> "/tmp/kam/'_tmp_z_b_assembly.fa'"
'/tmp/z/a/assembly.fa' -> "/tmp/kam/'_tmp_z_a_assembly.fa'"
$ 
23.11.2018 14:03 Honza
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Opet perfektni. Take dekuju.
Řešení 1× (Filip Jirsák)
Josef Kufner avatar 23.11.2018 12:08 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Odpovědět | | Sbalit | Link | Blokovat | Admin
Prostě stačí přejmenovat tak, že odstraníš lomítko.
rename 's/\///' */assembly.fa
Hello world ! Segmentation fault (core dumped)
23.11.2018 13:54 Honza
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Script od Andreje jeste chapu, rename 's/\///' */assembly.fa je na me uz hardcore. Ale taky to funguje. Take diky.
k3dAR avatar 23.11.2018 17:14 k3dAR | skóre: 62
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Jde o sed syntax 's/neco/zaneco/' s je najdi a zamen, / je vychozi oddelovac, protoze chces nahradit / musis ho escapovat znakem \, protoze nechces / nahradit ale odstranit tak "zaneco" nechas prazdne... pro lepsi pochopeni lze zmenit oddelovac na "cokoliv" jineho, treba #, pak by to u tebe bylo 's#/##', muzes si to vyzkouset se sedem:
echo "nazdar honzo" | sed 's/nazdar/ahoj/'
Pokud by se meli zmeni vsechny vyskyty na radku, pridas na konec g: 's/neco/zaneco/g'
porad nemam telo, ale uz mam hlavu... nobody
23.11.2018 17:47 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam

To je skript pro sed (stream editor). Úvodní s znamená nahrazení (substitute) a pak následují dva výrazy oddělené (v tomto případě) lomítky, první je regulární výraz a druhý je šablona k nahrazení. Nelze než doporučit manuálové stránky, protože tohle vyžaduje pochopení rour (pipe) a regulárních výrazů.

Ještě bych doplnil, že pro jednoduché případy umí přesně tohle i samotný shell při expanzi proměnných a není tedy nezbytně potřeba další proces.

text='aabbcc'
echo "${text}"          # aabbcc
echo "${text/b/z}"      # aazbcc
echo "${text//b/z}"     # aazzcc
echo "${text/[ac]/z}"   # zabbcc
echo "${text/%[ac]/z}"  # aabbcz
echo "${text//[ac]/z}"  # zzbbzz

Význam jednotlivých znaků je popsaný v man bash, kapitola Expansion / Parameter Expansion.

27.11.2018 08:58 Aleš Kapica | skóre: 51 | blog: kenyho_stesky | Ostrava
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Pozor. Tohle nemusí fungovat by default. Pro jistotu doporučuji do skriptu na začátek přidat:
…
shopt -s extglob
…
27.11.2018 12:13 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam

Žádný z mnou uvedených příkladů nevyžaduje extglob, pokud se nepletu. Ten bývá většinou implicitně zapnutý, ale aby ho člověk fakt využil, musel by tam jako pattern zapsat něco z tohoto:

       If  the  extglob  shell option is enabled using the shopt builtin, several
       extended pattern matching operators  are  recognized.   In  the  following
       description, a pattern-list is a list of one or more patterns separated by
       a |.  Composite patterns may be formed using one or more of the  following
       sub-patterns:

              ?(pattern-list)
                     Matches zero or one occurrence of the given patterns
              *(pattern-list)
                     Matches zero or more occurrences of the given patterns
              +(pattern-list)
                     Matches one or more occurrences of the given patterns
              @(pattern-list)
                     Matches one of the given patterns
              !(pattern-list)
                     Matches anything except one of the given patterns
27.11.2018 13:30 Aleš Kapica | skóre: 51 | blog: kenyho_stesky | Ostrava
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam
Dík za upřesnění. Využívám toho docela hodně, a bylo pro mne bylo docela překvapení, když byl ten extglob vypnutý, proto ho ve skriptech pro jistotu zapínám. Typicky toho využívám třeba v situaci, když chci ořezat textový řetězec, pro různé testy, atp.
23.11.2018 17:27 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: procházení adresářů a kopírování souborů a jejich přejmenování jinam

On to ale chtěl zkopírovat, zatímco rename všechno přesouvá (jako mv).

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.